Skip to content

Add option to disable panic recovery in message processing #4136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion v2/internal/app/app_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,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)
Expand Down
2 changes: 1 addition & 1 deletion v2/internal/app/app_production.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
52 changes: 28 additions & 24 deletions v2/internal/frontend/dispatcher/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions v2/pkg/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions website/docs/reference/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,13 @@ services of Apple and Microsoft.
Name: EnableFraudulentWebsiteDetection<br/>
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<br/>
Type: `bool`

### Bind

A slice of struct instances defining methods that need to be bound to the frontend.
Expand Down
1 change: 1 addition & 0 deletions website/src/pages/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added "Branding" section to `wails doctor` to correctly identify Windows 11 [#3891](https://github.com/wailsapp/wails/pull/3891) by [@ronen25](https://github.com/ronen25)
- Added `-skipembedcreate` flag to build and dev command to improve compile and recompile speed [#4143](https://github.com/wailsapp/wails/pull/4143) by @josStorer
- Added `DisablePanicRecovery` option to allow handle panics manually [#4136](https://github.com/wailsapp/wails/pull/4136) by [@APshenkin](https://github.com/APshenkin)

### Fixed
- Fixed -m build flag for dev command not working when recompiling in [#4141](https://github.com/wailsapp/wails/pull/4141) by @josStorer
Expand Down
Loading