From 90e66a7ad4efd471f1a1f8dc8ed504e911218a75 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 3 Jul 2023 19:52:50 +1000 Subject: [PATCH] [v3] Add PanicHandler application option. --- v3/pkg/application/application.go | 63 +++++++++++------------ v3/pkg/application/application_windows.go | 8 --- v3/pkg/application/options_application.go | 3 ++ 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index f584c56a6..b7207044e 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -157,6 +157,25 @@ type ( } ) +func processPanic(value any) { + if value == nil { + value = fmt.Errorf("unknown error") + } + if globalApplication.options.PanicHandler != nil { + globalApplication.options.PanicHandler(value) + return + } + // Print the panic details + fmt.Printf("Panic occurred: %v", value) + + // Print the stack trace + buf := make([]byte, 1<<16) + runtime.Stack(buf, true) + fmt.Println("Stack trace:") + fmt.Println(string(buf)) + os.Exit(1) +} + // Messages sent from javascript get routed here type windowMessage struct { windowId uint @@ -365,6 +384,14 @@ func (a *App) NewSystemTray() *SystemTray { func (a *App) Run() error { a.info("Starting application") + + // Setup panic handler + defer func() { + if err := recover(); err != nil { + processPanic(err) + } + }() + a.impl = newPlatformApp(a) go func() { for { @@ -683,14 +710,7 @@ func invokeSync(fn func()) { globalApplication.dispatchOnMainThread(func() { defer func() { if err := recover(); err != nil { - // Print the panic details - fmt.Println("Panic occurred:", err) - - // Print the stack trace - buf := make([]byte, 1<<16) - runtime.Stack(buf, true) - fmt.Println("Stack trace:") - fmt.Println(string(buf)) + processPanic(err) } }() fn() @@ -705,14 +725,7 @@ func invokeSyncWithResult[T any](fn func() T) (res T) { globalApplication.dispatchOnMainThread(func() { defer func() { if err := recover(); err != nil { - // Print the panic details - fmt.Println("Panic occurred:", err) - - // Print the stack trace - buf := make([]byte, 1<<16) - runtime.Stack(buf, true) - fmt.Println("Stack trace:") - fmt.Println(string(buf)) + processPanic(err) } }() res = fn() @@ -728,14 +741,7 @@ func invokeSyncWithError(fn func() error) (err error) { globalApplication.dispatchOnMainThread(func() { defer func() { if err := recover(); err != nil { - // Print the panic details - fmt.Println("Panic occurred:", err) - - // Print the stack trace - buf := make([]byte, 1<<16) - runtime.Stack(buf, true) - fmt.Println("Stack trace:") - fmt.Println(string(buf)) + processPanic(err) } }() err = fn() @@ -751,14 +757,7 @@ func invokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error globalApplication.dispatchOnMainThread(func() { defer func() { if err := recover(); err != nil { - // Print the panic details - fmt.Println("Panic occurred:", err) - - // Print the stack trace - buf := make([]byte, 1<<16) - runtime.Stack(buf, true) - fmt.Println("Stack trace:") - fmt.Println(string(buf)) + processPanic(err) } }() res, err = fn() diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index db478ef6c..e7a9c0d2e 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -172,20 +172,12 @@ func (m *windowsApp) setApplicationMenu(menu *Menu) { } func (m *windowsApp) run() error { - // Add a hook to the ApplicationDidFinishLaunching event - //m.parent.On(events.Mac.ApplicationDidFinishLaunching, func() { - // C.setApplicationShouldTerminateAfterLastWindowClosed(C.bool(m.parent.options.Mac.ApplicationShouldTerminateAfterLastWindowClosed)) - // C.setActivationPolicy(C.int(m.parent.options.Mac.ActivationPolicy)) - // C.activateIgnoringOtherApps() - //}) - // setup event listeners for eventID := range m.parent.applicationEventListeners { m.on(eventID) } _ = m.runMainLoop() - //C.run() return nil } diff --git a/v3/pkg/application/options_application.go b/v3/pkg/application/options_application.go index 001dd0529..7892822d0 100644 --- a/v3/pkg/application/options_application.go +++ b/v3/pkg/application/options_application.go @@ -21,6 +21,9 @@ type Options struct { Assets AssetOptions Plugins map[string]Plugin Flags map[string]any + + // PanicHandler is a way to register a custom panic handler + PanicHandler func(any) } // AssetOptions defines the configuration of the AssetServer.