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. Anullsnapshot is a no-op.onError- called with the error and stack trace whenever the snapshot's error changes. Defaults toZone.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
useFutureoruseStreamto 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
...Datavariants already call this for you.useFutureData,useStreamData,useMemoizedFutureData, anduseMemoizedStreamDatawire the handler internally and expose itsonErrorparameter, so reach for them when you only need the value plus error reporting. -
Pass
onErroronly when you have specific error UX. Without it the error reaches theZone, which is usually what you want - an unhandled async error should surface to the reporter, not be quietly logged and dropped.