Error reporting & alerts
A web stack trace is minified noise โ main.js all the way down. DartWay
alerts are built around app-state context instead: every reported error
carries the current route, the product features mounted on the screen, the
failed action or server call, the platform, app version and user.
โ Error
Failed call: faq.deleteQuestion
๐ Exception
PostgreSQLException: relation "faq" does not exist
๐ฅ web/android ยท v1.4.2 ยท user 42
๐ /admin/help
๐งฉ faq-admin, admin-shell
โก Call: faq.deleteQuestion
๐ StackTrace (top 8)
...
Out of the boxโ
With a standard DwCore setup there is nothing to install. Every error that
reaches the framework โ an uncaught zone error, a failed DwUiAction, an
AsyncValue error branch, a failed server call โ flows into one pipeline:
dw.handleErrorcaptures a context snapshot (dw.errorContext).DwCore.reportErrorfilters connection blips (they are UX, not alerts), dedupes the double report of a failed call, and sends the alert throughDwAlertsโ to Telegram whenDwTelegramAlertsConfigis set, to the log otherwise.
Two one-time wirings in the app make the context rich:
// The framework has no access to your router โ register the route source:
dw.errorContext.registerRouteSource(
() => router.routerDelegate.currentConfiguration.uri.path,
);
// Failed server calls report endpoint.method and show a network toast:
Client(url, onFailedCall: dwReportingOnFailedCall(
onConnectionError: (_, _) => dw.notify.error('Network error'),
));
Custom entries join every report: dw.errorContext.set('tenant', 'acme') or
dw.errorContext.register('cart', () => cart.id).
Features come for free: any widget implementing DwFeature (see the example
app) is picked up by DwFeature.scanMounted() at the moment of the error โ the
alert names the features of the screen where it happened.
Custom policyโ
Set DwConfig.onErrorReport to receive the full DwErrorReport (error,
stack, source, context snapshot) and route it anywhere โ the out-of-the-box
alerting steps aside automatically. The legacy globalErrorHandler
((error, stackTrace)) also disables it when overridden.
Action labels and confirmationsโ
dw.action(...) โ the only way to build a DwUiAction; its constructor is
private โ takes a label (names the action in reports; notification texts are
the fallback) and a confirmation:
dw.action(
(_) => dw.repo.saveModel(user.copyWith(role: role)),
label: 'changeUserRole',
confirmation: DwUiConfirmation('Change the role of $name?'),
)
Declining the dialog skips the action, its notifications and follow-ups. The
dialog defaults to a themed AlertDialog (DwConfirmDialog); supply
DwConfig.confirmDialogBuilder for a custom UI.