Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Errors

ErrorsProvider catches uncaught errors — window errors, unhandled promise rejections, and (in React) render errors — and dispatches them onto the Events bus as a normalized ArchitectError, so you can observe them from one place instead of wiring window.addEventListener yourself.

It’s included in defaultProviders:

import { Application, defaultProviders } from "@artisansdk/architect"

Application.configure().withProviders(defaultProviders).run()

What it catches

SourceTriggerNotes
"window"window.addEventListener("error", ...)Filtered to same-origin script files — drops extension/third-party-script noise and censored cross-origin "Script error." events
"promise"window.addEventListener("unhandledrejection", ...)
"react"ErrorBoundary’s componentDidCatchOnly if you’re using @artisansdk/architect/react’s ErrorBoundary (wrapped around your app by ApplicationProvider/ContextProvider)

ErrorsProvider.boot() is a no-op when window is undefined, so it’s safe under SSR — it just won’t catch anything until it runs in a browser.

Listening

ArchitectError sets a static label = "error", so you can listen by the class or the string:

import { Event } from "@artisansdk/architect/support/facades"
import { ArchitectError } from "@artisansdk/architect"

Event.listen(ArchitectError, (error) => {
  console.error(`[${error.source}]`, error.message, error.cause)
  reportToSentry(error)
})

// Equivalent — same channel
Event.listen("error", (error) => { /* ... */ })

ArchitectError shape

class ArchitectError extends Error {
  readonly source: "window" | "promise" | "react"
  readonly cause: unknown        // the original thrown value (inherited from Error)
  readonly errorInfo?: unknown   // React's componentStack info, only present for source "react"
}

message and stack are adopted from the original error when it’s a real Error instance, so reports point at the throw site rather than the wrapper.

React error boundaries

ApplicationProvider/ContextProvider from @artisansdk/architect/react wrap your app in an ErrorBoundary automatically:

import { ContextProvider } from "@artisansdk/architect/react"

<ContextProvider application={application} errorFallback={(error) => <p>Something broke.</p>}>
  <App />
</ContextProvider>

errorFallback renders in place of the crashed subtree. Dispatch to the Events bus is a separate side effect — it only fires if "events" is bound in the container, which ErrorsProvider (or EventsProvider) provides. Without either, the fallback still renders; the error just isn’t dispatched anywhere.

Bringing your own events wiring

If you’re not using defaultProviders, ErrorsProvider still only needs "events" to exist — it registers a Bus itself, guarded so it won’t replace one you’ve already bound:

import { Application, ErrorsProvider } from "@artisansdk/architect"

Application.configure()
  .withProviders([new ErrorsProvider()])
  .run()

See Events for the Bus API itself.