SH
Первый кейс с Maintenance
Здесь это нормальное состояние приложения (не эксепшн), поэтому должно прокидываться до экрана
Я, к сожалению, не в курсе твоей архитектуры, но как пример - если у тебя есть некий AppState, который слушает один из виджетов, допустим через bloc, то это могло бы быть следующее
Widget build(BuildContext context) {
AppStateBloc bloc = Provider.of<AppStateBloc>(context);
return StreamBuilder(
stream: bloc.appState,
builder: (_, snapshot) {
... // разбор состояний snapshot опустим
final AppState state = snapshot.data;
if (state is MaintenanceState)
return MaintenanceScreen(state) // можно передать state если там есть полезные данные для отображения на экране
...
return HomeScreen()
}
);
}
Случай с Unauthorized - это Service Layer. Допустим у тебя есть некий абстрактный класс Query и есть NetworkClient который умеет их выполнять
abstract class Query<T> {
...
}
abstract class NetworkClient {
Future<dynamic> execute(Query<dynamic> query);
}
Ну и соответственно, уровнем выше, скажем, есть у тебя Repository, который работает с этим клиентом и запросами
Так вот обработку Unathorized можно сделать централизованно внутри NetworkClient
То есть при запуске каждого Query он слушает результат - если прилетает нормальное значение - передаем в ответ
если прилетел Unauthorized - пытаемся отрефрешить токен и дергаем счетчик
если, скажем, три раза были неуспешными - тогда уже прокидываем какое-нибудь специальное состояние до Presentation Layer
где пользователю уже покажем соотв экран
Сейчас есть один монолитный класс ApiHelper, с методом runQuery (дергает запрос на GraphQLClient, и он же пытается лезть в Auth и рефрешить токен), метод universalRequest (дергает runQuery с параметрами) и куча методов запроса конкретных данных (login, checkToken, transactions и т.д.), это всё эвэйт universalRequest с разным payload и возвращение результата. И всё это, вдобавок, тупо статикой сделано.