Skip to main content

useAsyncSnapshotErrorHandler

Watches an AsyncSnapshot and reports its error once, when it appears. It is the piece that stops an error returned by useFuture or useStream from sitting silently in snapshot.error.

String useUserName(BuildContext context, UserService service, String userId) {
final snapshot = useMemoizedFuture(() => service.loadName(userId), keys: [userId]);

// Surfaces the error once, when it appears - without this the error would be
// silently stuck in snapshot.error.
useAsyncSnapshotErrorHandler(
snapshot,
onError: (error, stackTrace) => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed: $error')),
),
);

return snapshot.data ?? 'Loading...';
}

Signature

void useAsyncSnapshotErrorHandler(
AsyncSnapshot<Object?>? snapshot, {
void Function(Object, StackTrace)? onError,
});
  • snapshot - the snapshot to watch. A null snapshot is a no-op.
  • onError - called with the error and stack trace whenever the snapshot's error changes. Defaults to Zone.current.handleUncaughtError, which usually feeds the app-wide error reporter (for example Crashlytics).

The handler fires when snapshot.error (or its stack trace) changes, so each distinct error is reported once rather than on every rebuild.

Use cases

  • Pairing with useFuture or useStream to make sure an emitted error is not swallowed.
  • Routing async errors to a user-facing surface - a snackbar, a dialog - via onError, while leaving everything else to the default reporter.

Caveats

  • The ...Data variants already call this for you. useFutureData, useStreamData, useMemoizedFutureData, and useMemoizedStreamData wire the handler internally and expose its onError parameter, so reach for them when you only need the value plus error reporting.

  • Pass onError only when you have specific error UX. Without it the error reaches the Zone, which is usually what you want - an unhandled async error should surface to the reporter, not be quietly logged and dropped.

See also

  • useFuture - the most common source of the snapshot
  • useStream - the streaming counterpart
  • useEffect - the primitive this hook is built on