getUser method
- bool notify = true,
Fetches the current user from the API, persists the result, and optionally broadcasts it on the user stream.
When notify is true (the default) the fetched UserModel is added to
user. Pass notify: false during startup to resolve the user silently
without triggering downstream listeners.
Throws FormatException if the API response cannot be parsed. Throws DioException on network errors.
Implementation
Future<UserModel> getUser({bool notify = true}) async {
_logger.info('[UserRepository] Fetching user from API');
// TODO: swap getDummyUser() → getUser() when API is ready
final Response<dynamic> response = await _userService.getDummyUser();
if (response.data is! Map) {
_logger.warn(
'[UserRepository] getUser: unexpected response shape',
extras: <String, Object?>{'type': response.data.runtimeType.toString()},
escalate: true,
);
final UserModel? cached = await _secureStorage.getUserModel();
if (cached != null) {
_setSentryUser(cached);
if (notify && !_userController.isClosed) _userController.add(cached);
return cached;
}
throw const FormatException('getUser: unexpected response shape and no cached user');
}
final Map<String, dynamic> json = Map<String, dynamic>.from(response.data as Map);
final dynamic rawData = json['data'];
final Map<String, dynamic> userData = rawData is Map ? Map<String, dynamic>.from(rawData) : json;
final UserModel? user = UserModel.tryFromJson(userData);
if (user == null) {
_logger.error('[UserRepository] Failed to parse user from API response', extras: <String, Object?>{'response': json.toString()});
throw const FormatException('Failed to parse user response');
}
_logger.info(
'[UserRepository] User fetched successfully: '
'${user.firstName} ${user.lastName}',
);
await _secureStorage.setUserModel(user);
_setSentryUser(user);
if (notify && !_userController.isClosed) {
_userController.add(user);
}
return user;
}