Руководства

Корневая граница на чистом Dart

Модель оценки, ограниченный контекст, ErrorReporter, корневая Zone и управляемое завершение.

v0.1.0-dev.1Начальный уровень

Корневая граница на чистом Dart

Пример имитирует необработанную асинхронную ошибку процесса каталога. Приложение классифицирует её как недоступность интеграции, добавляет два ограниченных факта запроса, создаёт очищенный ErrorReport, записывает его через DeveloperLogErrorReporter и перед завершением ждёт принятую работу.

Сервис с ошибкой не получает ErrorManager. Необработанная ошибка достигает Zone, которой уже владеет приложение.

01

Установите пакет

shell
dart pub add ark_error_manager:^0.1.0-dev.1
02

Опишите среду выполнения

dart
const ErrorRuntimeEnvironment environment = ErrorRuntimeEnvironment(
  buildMode: ErrorBuildMode.release,
  deployment: ErrorDeploymentEnvironment.production,
  application: ErrorApplicationInfo(
    name: 'Catalog worker',
    version: '1.4.0',
    buildNumber: '87',
  ),
);

Режим сборки и среда развёртывания задаются отдельно: release-сборка может работать со staging, а profile-сборка — с production.

03

Добавьте ErrorClassifier приложения

dart
final class ServiceUnavailableClassifier
    extends TypedErrorClassifier<ServiceUnavailableException> {
  const ServiceUnavailableClassifier();

  @override
  ErrorAssessment classifyError(
    ServiceUnavailableException error,
    ErrorOccurrence occurrence,
    ErrorRuntimeEnvironment environment,
  ) => const ErrorAssessment(
    category: ErrorCategory.integration,
    severity: ErrorSeverity.degraded,
  );
}
04

Добавьте ограниченный диагностический контекст

dart
final class RequestContextProvider implements ErrorContextProvider {
  const RequestContextProvider();

  @override
  ErrorContextSection collect(
    ErrorOccurrence occurrence,
    ErrorRuntimeEnvironment environment,
  ) => ErrorContextSection(
    name: 'request',
    fields: <String, Object?>{
      'method': 'GET',
      'endpoint': '/catalog',
    },
  );
}

Контекст намеренно мал. В него не входят Header, тело запроса, учётные данные или полное состояние приложения.

05

Создайте менеджер

dart
final ErrorManager manager = ErrorManager(
  configuration: ErrorManagerConfiguration(
    environment: environment,
    classifiers: const <ErrorClassifier>[
      ServiceUnavailableClassifier(),
    ],
    contextProviders: const <ErrorContextProvider>[
      RequestContextProvider(),
    ],
    reporters: const <ErrorReporter>[
      DeveloperLogErrorReporter(name: 'catalog.worker'),
    ],
  ),
);

Встроенный резервный классификатор по-прежнему обработает ошибки, которые не поддержал пользовательский ErrorClassifier.

06

Подключите принадлежащую приложению Zone

dart
final captured = Completer<void>();

runZonedGuarded(
  () {
    scheduleMicrotask(() {
      throw const ServiceUnavailableException('catalog');
    });
  },
  (error, stackTrace) {
    manager.onUncaughtZoneError(error, stackTrace);
    captured.complete();
  },
);

await captured.future;

Пакет не создаёт Zone. Приложение сохраняет контроль над zoneValues, ZoneSpecification и вложенными границами.

07

Завершите управляемый процесс

dart
await manager.flush();
await manager.close();

После close повторное использование менеджера запрещено.

Проследите ошибку по цепочке обработки

  1. Zone создаёт ErrorOccurrence с ErrorCaptureSource.zone.
  2. ServiceUnavailableClassifier возвращает оценку Integration/Degraded.
  3. RequestContextProvider добавляет только HTTP-метод и адрес ресурса.
  4. Настроенная Policy решает, нужен ли отчёт, показ или восстановление.
  5. Sanitizer создаёт отдельный ErrorReport.
  6. DeveloperLogErrorReporter получает ErrorReport, но не исходный ErrorIncident.
  7. flush подтверждает завершение всей принятой работы до close.

Запустите полный пример по ссылке. Заменяйте DeveloperLogErrorReporter только после изучения раздела «Безопасность» и определения правил транспорта, хранения, доступа и удаления данных в целевой системе.

ARKTELOS

Инженерные системы для программного обеспечения, которое обязано выдерживать нагрузку.