Learn

Choose the correct handling path

Decide whether a failure belongs in a typed result, local recovery, ordinary propagation, or the application-level error pipeline.

v0.1.0-dev.1Beginner

Choose the correct handling path

Ark Error Manager is not the first destination for every failure. Most application code should continue to use normal return values, typed failure results, try/catch, and ordinary error propagation. The manager coordinates the smaller set of incidents that reach an application boundary or explicitly require an application-wide decision.

Classify the outcome before choosing an API

SituationCorrect pathWhy
Form validation rejects inputTyped validation stateThe application expects this outcome.
A search returns no itemsEmpty domain resultNothing exceptional occurred.
Optional cache read fails but remote loading succeedsRecover locally; optionally record bounded diagnosticsThe operation has a valid fallback.
Repository cannot complete and its caller owns retry policyThrow or return a typed failure to the callerThe decision still belongs to a local boundary.
Unhandled asynchronous error escapes the application taskRoot ZoneThe error has reached the host boundary.
Flutter framework callback reports a build or paint failureFlutterError.onError bindingFlutter already owns the capture point.
Child Isolate terminates with an unhandled errorIsolate error-port bindingZones do not cross Isolate boundaries.
Integration code must consume an exception and return a fallback, but reporting or recovery is still requiredOne deliberate handleError or captureError callNormal propagation has been intentionally stopped.

A local catch has three honest outcomes

dart
try {
  return await client.load();
} catch (error, stackTrace) {
  // Choose exactly one primary path:
  // 1. recover and return a normal result;
  // 2. transform or rethrow for the caller;
  // 3. submit once because this boundary consumes the error.
}

Recover locally

Return a fallback only when the domain accepts it as a valid result. Do not report the same failure globally merely because a catch block ran.

Preserve propagation

Use rethrow when a caller or root boundary still owns the decision. This retains the original stack trace and avoids a second reporting path.

Submit deliberately

Call handleError when the local boundary must wait until reporting, presentation, and recovery have completed. Call captureError when queueing the incident is enough. After submitting, do not rethrow into another configured boundary unless the application has an explicit deduplication identity and policy.

One failure, one application-level submission

Duplicate incidents commonly appear when:

  1. a feature catches and submits an error;
  2. the feature rethrows it;
  3. a Zone or Flutter hook captures it again;
  4. a preserved previous Flutter handler sends it to another crash reporter.

Choose one owner for remote reporting. If a previous handler must remain active, decide which system reports externally and how both systems correlate or deduplicate the incident.

Where ErrorManager is available

The application Bootstrap or Composition Root owns the manager and passes callbacks only to infrastructure bindings that genuinely need them. UseCases, Presenters, repositories, DataSources, and widgets keep their existing error contracts. They do not resolve a global manager.

The handled-error recipe is therefore an exception for a specific integration boundary, not a template to paste around every method.

Continue from here

  1. Read Ownership and boundaries to place the manager.
  2. Read Ordered processing pipeline to understand what happens after submission.
  3. Build the pure-Dart error boundary or Flutter root integration.
  4. Review Security and privacy before connecting a remote ErrorReporter.
ARKTELOS

Purpose-built engineering systems for software that has to hold.