diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index 89265c9b9..347daac05 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -212,7 +212,7 @@ func CreateApp(appoptions *options.App) (*App, error) { eventHandler := runtime.NewEvents(myLogger) ctx = context.WithValue(ctx, "events", eventHandler) - messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter) + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter, appoptions.DisablePanicRecovery) // Create the frontends and register to event handler desktopFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) diff --git a/v2/internal/app/app_production.go b/v2/internal/app/app_production.go index 4c217b17c..9eb0e5a66 100644 --- a/v2/internal/app/app_production.go +++ b/v2/internal/app/app_production.go @@ -82,7 +82,7 @@ func CreateApp(appoptions *options.App) (*App, error) { ctx = context.WithValue(ctx, "buildtype", "production") } - messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter) + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter, appoptions.DisablePanicRecovery) appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) eventHandler.AddFrontend(appFrontend) diff --git a/v2/internal/frontend/dispatcher/dispatcher.go b/v2/internal/frontend/dispatcher/dispatcher.go index 60a99f467..24a43cfef 100644 --- a/v2/internal/frontend/dispatcher/dispatcher.go +++ b/v2/internal/frontend/dispatcher/dispatcher.go @@ -11,38 +11,42 @@ import ( ) type Dispatcher struct { - log *logger.Logger - bindings *binding.Bindings - events frontend.Events - bindingsDB *binding.DB - ctx context.Context - errfmt options.ErrorFormatter + log *logger.Logger + bindings *binding.Bindings + events frontend.Events + bindingsDB *binding.DB + ctx context.Context + errfmt options.ErrorFormatter + disablePanicRecovery bool } -func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events, errfmt options.ErrorFormatter) *Dispatcher { +func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events, errfmt options.ErrorFormatter, disablePanicRecovery bool) *Dispatcher { return &Dispatcher{ - log: log, - bindings: bindings, - events: events, - bindingsDB: bindings.DB(), - ctx: ctx, - errfmt: errfmt, + log: log, + bindings: bindings, + events: events, + bindingsDB: bindings.DB(), + ctx: ctx, + errfmt: errfmt, + disablePanicRecovery: disablePanicRecovery, } } func (d *Dispatcher) ProcessMessage(message string, sender frontend.Frontend) (_ string, err error) { - defer func() { - if e := recover(); e != nil { - if errPanic, ok := e.(error); ok { - err = errPanic - } else { - err = fmt.Errorf("%v", e) + if !d.disablePanicRecovery { + defer func() { + if e := recover(); e != nil { + if errPanic, ok := e.(error); ok { + err = errPanic + } else { + err = fmt.Errorf("%v", e) + } } - } - if err != nil { - d.log.Error("process message error: %s -> %s", message, err) - } - }() + if err != nil { + d.log.Error("process message error: %s -> %s", message, err) + } + }() + } if message == "" { return "", errors.New("No message to process") diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 282a25691..082ac48cd 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -98,6 +98,9 @@ type App struct { // DragAndDrop options for drag and drop behavior DragAndDrop *DragAndDrop + + // DisablePanicRecovery disables the panic recovery system in messages processing + DisablePanicRecovery bool } type ErrorFormatter func(error) any diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx index efcc67961..9d999f421 100644 --- a/website/docs/reference/options.mdx +++ b/website/docs/reference/options.mdx @@ -487,6 +487,13 @@ services of Apple and Microsoft. Name: EnableFraudulentWebsiteDetection
Type: `bool` +### DisablePanicRecovery + +DisablePanicRecovery disables the automatic recovery from panics in message processing. By default, Wails will recover from panics in message processing and log the error. If you want to handle panics yourself, set this to `true`. + +Name: DisablePanicRecovery
+Type: `bool` + ### Bind A slice of struct instances defining methods that need to be bound to the frontend.