onUncaughtError property

void Function(Object error, StackTrace stackTrace)? onUncaughtError
getter/setter pair

Called when an error escapes an interpreted callback that the platform invoked outside the script's own future chain.

A Stream.listen callback, a handleError handler and a Timer body are all invoked by the platform, not by the script. When one of them throws, native Dart sends the error to the current Zone and lets the enclosing main() return normally — and d4rt matches that. The problem it leaves behind is that Zone, runZoned and runZonedGuarded are deliberately unbridged (see unbridged_reasons.dart), so an interpreted script has no way at all to observe its own callback failing. This hook is the embedder's way in.

The error handed to the hook is the value the script actually threw. The interpreter's internal InternalInterpreterD4rtException wrapper is removed first, so this path agrees with the synchronous one, where execute already rethrows the original value.

Setting a hook contains the error: it is reported here and not forwarded to the enclosing zone, which is what makes it usable as a sandbox boundary by a host that runs untrusted script.

Errors the caller can already observe are not routed here — anything that propagates through execute's return value or thrown exception stays on that path.

Set this before calling execute, and understand that setting it makes d4rt own the error zone for the execution. That is what allows the errors to be caught at all, but it also means a Future created by the embedder before execute and passed into the script reports its errors to the embedder's zone rather than to the script — the ordinary consequence of an error-zone boundary, and the reason this is opt-in. Leaving it null keeps the pre-existing routing untouched: escapes reach the enclosing zone, still wrapped in the interpreter's internal exception type.

Example:

final runner = D4rtRunner();
runner.onUncaughtError = (error, stackTrace) {
  log.warning('script callback failed', error, stackTrace);
};

Implementation

void Function(Object error, StackTrace stackTrace)? onUncaughtError;