Skip to main content

Error Boundary

Catches panics during build, layout, paint, and hit-testing, displaying fallback UI instead of crashing the app.

Basic Usage

widgets.ErrorBoundary{
Child: riskyWidget,
FallbackBuilder: func(err *drifterrors.BoundaryError) core.Widget {
return widgets.Text{Content: "Something went wrong"}
},
OnError: func(err *drifterrors.BoundaryError) {
log.Printf("Widget error: %v", err)
},
}

Properties

PropertyTypeDescription
Childcore.WidgetThe widget tree to protect
FallbackBuilderfunc(*BoundaryError) WidgetBuilds fallback UI when an error is caught
OnErrorfunc(*BoundaryError)Called when an error is caught

Error Widgets

WidgetPurpose
ErrorWidgetInline error display (default fallback)
DebugErrorScreenFull-screen error with stack trace (debug mode)

Programmatic Control

Access the boundary's state from descendant widgets:

state := widgets.ErrorBoundaryOf(ctx)
if state != nil && state.HasError() {
state.Reset() // Clear error and retry rendering
}

Common Patterns

Scoped Error Handling

Wrap specific subtrees to isolate failures:

widgets.Column{
Children: []core.Widget{
HeaderWidget{}, // Keeps working
widgets.ErrorBoundary{
Child: RiskyWidget{},
FallbackBuilder: func(err *drifterrors.BoundaryError) core.Widget {
return widgets.Text{Content: "Failed to load"}
},
},
FooterWidget{}, // Keeps working
},
}

Global Error Handling

Wrap the entire app for production:

func main() {
drift.NewApp(widgets.ErrorBoundary{
Child: MyApp{},
FallbackBuilder: func(err *drifterrors.BoundaryError) core.Widget {
return MyCustomErrorScreen{Error: err}
},
}).Run()
}