fix(di): улучшить обработку ошибок при инициализации репозиториев (#34)

* fix(di): улучшить обработку ошибок при инициализации репозиториев
* fix(di): улучшить обработку ошибок при инициализации репозиториев и сервисов

---------

Co-authored-by: petrovyuri <petrovyuri@example.com>
This commit is contained in:
Yuri Petrov
2025-10-23 12:00:09 +03:00
committed by GitHub
parent 5d93fb1713
commit 42b7c34d1a
3 changed files with 72 additions and 89 deletions

View File

@@ -74,88 +74,57 @@ final class DiRepositories {
required DiContainer diContainer, required DiContainer diContainer,
}) { }) {
onProgress('Начинаем инициализацию репозиториев...'); onProgress('Начинаем инициализацию репозиториев...');
try {
// Инициализация репозитория обновлений
updatesRepository = _lazyInitRepo<IUpdateRepository>(
mockFactory: UpdateMockRepository.new,
mainFactory: UpdateRepository.new,
onProgress: onProgress,
environment: diContainer.env,
);
onProgress(updatesRepository.name);
} on Object catch (error, stackTrace) {
onError(
'Ошибка инициализации репозитория IUpdateRepository',
error,
stackTrace,
);
}
try { // Инициализация репозитория обновлений
// Инициализация репозитория авторизации updatesRepository = _lazyInitRepo<IUpdateRepository>(
authRepository = _lazyInitRepo<IAuthRepository>( mockFactory: UpdateMockRepository.new,
mockFactory: AuthMockRepository.new, mainFactory: UpdateRepository.new,
mainFactory: () => AuthRepository( onProgress: onProgress,
httpClient: diContainer.httpClientFactory( onError: onError,
diContainer.debugService, environment: diContainer.env,
diContainer.appConfig, );
),
),
onProgress: onProgress,
environment: diContainer.env,
);
onProgress(authRepository.name);
} on Object catch (error, stackTrace) {
onError(
'Ошибка инициализации репозитория IAuthRepository',
error,
stackTrace,
);
}
try { // Инициализация репозитория авторизации
// Инициализация репозитория сервиса управления токеном доступа authRepository = _lazyInitRepo<IAuthRepository>(
mainRepository = _lazyInitRepo<IMainRepository>( mockFactory: AuthMockRepository.new,
mockFactory: MainMockRepository.new, mainFactory: () => AuthRepository(
mainFactory: () => MainRepository( httpClient: diContainer.httpClientFactory(
httpClient: diContainer.httpClientFactory( diContainer.debugService,
diContainer.debugService, diContainer.appConfig,
diContainer.appConfig,
),
), ),
onProgress: onProgress, ),
environment: diContainer.env, onProgress: onProgress,
); onError: onError,
onProgress(mainRepository.name); environment: diContainer.env,
} on Object catch (error, stackTrace) { );
onError(
'Ошибка инициализации репозитория IMainRepository',
error,
stackTrace,
);
}
try { // Инициализация репозитория сервиса управления токеном доступа
// Инициализация репозитория профиля mainRepository = _lazyInitRepo<IMainRepository>(
profileRepository = _lazyInitRepo<IProfileRepository>( mockFactory: MainMockRepository.new,
mockFactory: ProfileMockRepository.new, mainFactory: () => MainRepository(
mainFactory: () => ProfileRepository( httpClient: diContainer.httpClientFactory(
httpClient: diContainer.httpClientFactory( diContainer.debugService,
diContainer.debugService, diContainer.appConfig,
diContainer.appConfig,
),
), ),
onProgress: onProgress, ),
environment: diContainer.env, onProgress: onProgress,
); onError: onError,
onProgress(profileRepository.name); environment: diContainer.env,
} on Object catch (error, stackTrace) { );
onError(
'Ошибка инициализации репозитория IProfileRepository', // Инициализация репозитория профиля
error, profileRepository = _lazyInitRepo<IProfileRepository>(
stackTrace, mockFactory: ProfileMockRepository.new,
); mainFactory: () => ProfileRepository(
} httpClient: diContainer.httpClientFactory(
diContainer.debugService,
diContainer.appConfig,
),
),
onProgress: onProgress,
onError: onError,
environment: diContainer.env,
);
onProgress( onProgress(
'Инициализация репозиториев завершена! Было подменено репозиториев - ${_mockReposToSwitch.length} (${_mockReposToSwitch.join(', ')})', 'Инициализация репозиториев завершена! Было подменено репозиториев - ${_mockReposToSwitch.length} (${_mockReposToSwitch.join(', ')})',
@@ -169,26 +138,36 @@ final class DiRepositories {
/// - [mockFactory] - функция-фабрика для инициализации мокового репозитория /// - [mockFactory] - функция-фабрика для инициализации мокового репозитория
/// - [mainFactory] - функция-фабрика для инициализации основного репозитория /// - [mainFactory] - функция-фабрика для инициализации основного репозитория
/// - [onProgress] - обратный вызов для уведомления о прогрессе /// - [onProgress] - обратный вызов для уведомления о прогрессе
/// - [onError] - обратный вызов для обработки ошибок инициализации
/// - [environment] - окружение приложения для определения стратегии инициализации /// - [environment] - окружение приложения для определения стратегии инициализации
/// ///
/// Возвращает: /// Возвращает:
/// - Экземпляр репозитория в зависимости от окружения /// - Экземпляр репозитория в зависимости от окружения
///
/// Throws:
/// - Перебрасывает исключение, если инициализация репозитория завершилась с ошибкой
T _lazyInitRepo<T extends DiBaseRepo>({ T _lazyInitRepo<T extends DiBaseRepo>({
required AppEnv environment, required AppEnv environment,
required T Function() mainFactory, required T Function() mainFactory,
required T Function() mockFactory, required T Function() mockFactory,
required OnProgress onProgress, required OnProgress onProgress,
required OnError onError,
}) { }) {
// TODO(yura): https://github.com/smmarty/friflex_flutter_starter/issues/31 - добавить onError try {
final repo = switch (environment) {
AppEnv.dev => mockFactory(),
AppEnv.prod => mainFactory(),
AppEnv.stage =>
_mockReposToSwitch.contains(T) ? mockFactory() : mainFactory(),
};
final repo = switch (environment) { // throw Exception('Тестовая - ошибка инициализации репозитория $T');
AppEnv.dev => mockFactory(), onProgress(repo.name);
AppEnv.prod => mainFactory(), return repo;
AppEnv.stage => } on Object catch (error, stackTrace) {
_mockReposToSwitch.contains(T) ? mockFactory() : mainFactory(), onError('Ошибка инициализации репозитория $T', error, stackTrace);
}; // Перебрасываем исключение дальше, чтобы не скрыть ошибку инициализации
rethrow;
onProgress(repo.name); }
return repo;
} }
} }

View File

@@ -41,6 +41,7 @@ final class DiServices {
required DiContainer diContainer, required DiContainer diContainer,
}) { }) {
try { try {
// throw Exception('Тестовая - ошибка инициализации сервиса путей');
pathProvider = const AppPathProvider(); pathProvider = const AppPathProvider();
onProgress(AppPathProvider.name); onProgress(AppPathProvider.name);
} on Object catch (error, stackTrace) { } on Object catch (error, stackTrace) {

View File

@@ -134,8 +134,11 @@ class AppRunner {
..logOnComplete(name) ..logOnComplete(name)
..stop(); ..stop();
}, },
onError: (message, error, [stackTrace]) => onError: (message, error, [stackTrace]) {
debugService.logError(message, error: error, stackTrace: stackTrace), timerRunner.stop();
_debugService.logError(message, error: error, stackTrace: stackTrace);
throw Exception('Ошибка инициализации зависимостей: $message');
},
); );
//throw Exception('Test error'); //throw Exception('Test error');
return diContainer; return diContainer;