mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Compare commits
1 commit
master
...
vk/c544-pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca206452cd |
3 changed files with 121 additions and 0 deletions
|
|
@ -501,6 +501,8 @@ func (f *Frontend) processMessage(message string) {
|
|||
}
|
||||
|
||||
go func() {
|
||||
defer handlePanic(f.frontendOptions.PanicHandler, f.logger)
|
||||
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
|
|
|
|||
100
v2/internal/frontend/desktop/linux/panic_handler.go
Normal file
100
v2/internal/frontend/desktop/linux/panic_handler.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
func getStackTrace(skipStart int, skipEnd int) string {
|
||||
// Get all program counters first
|
||||
pc := make([]uintptr, 32)
|
||||
n := runtime.Callers(skipStart+1, pc)
|
||||
if n == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
pc = pc[:n]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
|
||||
// Collect all frames first
|
||||
var allFrames []runtime.Frame
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
allFrames = append(allFrames, frame)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Remove frames from the end
|
||||
if len(allFrames) > skipEnd {
|
||||
allFrames = allFrames[:len(allFrames)-skipEnd]
|
||||
}
|
||||
|
||||
// Build the output string
|
||||
var builder strings.Builder
|
||||
for _, frame := range allFrames {
|
||||
fmt.Fprintf(&builder, "%s\n\tat %s:%d\n",
|
||||
frame.Function, frame.File, frame.Line)
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
type handlePanicOptions struct {
|
||||
skipEnd int
|
||||
}
|
||||
|
||||
func newPanicDetails(err error, trace string) *options.PanicDetails {
|
||||
return &options.PanicDetails{
|
||||
Error: err,
|
||||
Time: time.Now(),
|
||||
StackTrace: trace,
|
||||
FullStackTrace: string(debug.Stack()),
|
||||
}
|
||||
}
|
||||
|
||||
// handlePanic recovers from panics and processes them through the configured handler.
|
||||
// Returns true if a panic was recovered.
|
||||
func handlePanic(handler options.PanicHandler, logger interface{ Error(string, ...interface{}) }, opts ...handlePanicOptions) bool {
|
||||
// Try to recover
|
||||
e := recover()
|
||||
if e == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the error
|
||||
err, ok := e.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", e)
|
||||
}
|
||||
|
||||
// Get the stack trace
|
||||
var stackTrace string
|
||||
skipEnd := 0
|
||||
if len(opts) > 0 {
|
||||
skipEnd = opts[0].skipEnd
|
||||
}
|
||||
stackTrace = getStackTrace(3, skipEnd)
|
||||
|
||||
panicDetails := newPanicDetails(err, stackTrace)
|
||||
|
||||
// Use custom handler if provided
|
||||
if handler != nil {
|
||||
handler(panicDetails)
|
||||
return true
|
||||
}
|
||||
|
||||
// Default behavior: log the panic
|
||||
if logger != nil {
|
||||
logger.Error("panic error: %v\n%s", panicDetails.Error, panicDetails.StackTrace)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/linux"
|
||||
|
|
@ -69,6 +70,12 @@ type App struct {
|
|||
// ErrorFormatter overrides the formatting of errors returned by backend methods
|
||||
ErrorFormatter ErrorFormatter
|
||||
|
||||
// PanicHandler is called when a panic occurs in a bound method.
|
||||
// If not set, the panic will be logged and the application will continue.
|
||||
// This is particularly useful on Linux where panics in cgo callbacks
|
||||
// can cause signal handler issues.
|
||||
PanicHandler PanicHandler
|
||||
|
||||
// CSS property to test for draggable elements. Default "--wails-draggable"
|
||||
CSSDragProperty string
|
||||
|
||||
|
|
@ -108,6 +115,18 @@ type App struct {
|
|||
|
||||
type ErrorFormatter func(error) any
|
||||
|
||||
// PanicDetails contains information about a panic that occurred in a bound method
|
||||
type PanicDetails struct {
|
||||
StackTrace string
|
||||
Error error
|
||||
Time time.Time
|
||||
FullStackTrace string
|
||||
}
|
||||
|
||||
// PanicHandler is a function that handles panics in bound methods.
|
||||
// If not set, panics will be logged to the application logger.
|
||||
type PanicHandler func(*PanicDetails)
|
||||
|
||||
type RGBA struct {
|
||||
R uint8 `json:"r"`
|
||||
G uint8 `json:"g"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue