Руководства
Корневая интеграция Flutter
Обработчики Flutter Framework и Platform внутри принадлежащей приложению Zone и показ через корневой Navigator.
Корневая интеграция Flutter
В руководстве один менеджер ядра подключается к трём корневым путям типичного Flutter-приложения: Zone приложения, отчётности Flutter Framework и необработанным ошибкам корневого Isolate через PlatformDispatcher. Для дочерних Isolate по-прежнему нужна отдельная явная привязка.
ошибка Zone ───────────────┐
FlutterError.onError ──────┼─→ одна цепочка ErrorManager
ошибка PlatformDispatcher ┘
Установите Flutter-пакет
flutter pub add ark_error_manager_flutter:^0.1.0-dev.1
Пакет экспортирует публичный API ядра, поэтому файлу инициализации достаточно одного импорта.
Задайте владельца состояния инициализации
final class ApplicationBootstrap {
ErrorManager? _manager;
FlutterErrorManagerBinding? _binding;
void run() => runZonedGuarded(_start, _onZoneError);
}
Поле с типом, допускающим null, позволяет использовать прямой резервный путь, если ошибка возникла при создании самого менеджера.
Создайте и подключите объекты внутри Zone
void _start() {
WidgetsFlutterBinding.ensureInitialized();
final navigatorKey = GlobalKey<NavigatorState>();
final manager = ErrorManager(
configuration: ErrorManagerConfiguration(
environment: FlutterErrorBuildMode.environment(
deployment: ErrorDeploymentEnvironment.production,
application: const ErrorApplicationInfo(
name: 'Example application',
version: '1.0.0',
),
),
classifiers: const <ErrorClassifier>[
FlutterFrameworkErrorClassifier(),
],
contextProviders: <ErrorContextProvider>[
FlutterRuntimeErrorContextProvider(),
],
reporters: const <ErrorReporter>[DeveloperLogErrorReporter()],
presenter: NavigatorErrorPresenter(
navigatorKey: navigatorKey,
delegate: const ApplicationErrorPresentationDelegate(),
),
),
);
final binding = FlutterErrorManagerBinding(manager: manager)..attach();
_manager = manager;
_binding = binding;
runApp(Application(navigatorKey: navigatorKey));
}
Обработайте ошибку создания менеджера
void _onZoneError(Object error, StackTrace stackTrace) {
final manager = _manager;
if (manager == null) {
Zone.root.handleUncaughtError(error, stackTrace);
return;
}
manager.onUncaughtZoneError(error, stackTrace);
}
FlutterErrorManagerBinding и менеджер остаются у объекта инициализации. Виджеты, Presenter, UseCase, Repository и Provider их не получают.
Реализуйте принадлежащий приложению показ
final class ApplicationErrorPresentationDelegate
implements FlutterErrorPresentationDelegate {
const ApplicationErrorPresentationDelegate();
@override
Future<void> present(
BuildContext? context,
ErrorIncident incident,
ErrorPresentationDirective directive,
) async {
if (context == null || directive == ErrorPresentationDirective.none) {
return;
}
await showDialog<void>(
context: context,
barrierDismissible: directive != ErrorPresentationDirective.blocking,
builder: (context) => const AlertDialog(
title: Text('Произошла ошибка'),
content: Text('Повторите операцию.'),
),
);
}
}
Delegate получает исходный локальный Incident, потому что может выбирать UI по Category, Severity и Policy. Не показывайте пользователю текст исключения, StackTrace или произвольные поля контекста.
Проверьте путь Flutter Framework
FlutterError.reportError(
FlutterErrorDetails(
exception: StateError('Example framework failure'),
stack: StackTrace.current,
library: 'catalog example',
context: ErrorDescription('while handling the example action'),
),
);
Используется штатный API отчётности Flutter. FlutterErrorManagerBinding получает ошибку через FlutterError.onError; экран не получает менеджер.
Владение при завершении
Мобильное приложение часто завершается вместе с процессом, но у тестов, Desktop Shell, встроенного Flutter Host и управляемого перезапуска есть настоящий порядок завершения:
binding.detach();
await manager.flush();
await manager.close();
Сначала отключите привязку, чтобы глобальный обратный вызов не передал новый ErrorIncident во время закрытия. Сохраняйте объект привязки: он владеет ссылками на предыдущие обработчики и может безопасно восстановить их.
Исключите дублирование отчётов
Политика предыдущего Handler по умолчанию сохраняет штатную диагностику Flutter. Если прежний FlutterError.onError уже отправляет ошибки во внешнюю систему, определите единственного владельца удалённой отчётности. Два сохранённых внешних Reporter без дедупликации могут отправить одну ошибку дважды.