-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'v3-alpha' into v3/bindgen-fixes
- Loading branch information
Showing
23 changed files
with
398 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
--- | ||
title: Handling Panics | ||
description: How to handle panics in your Wails application | ||
--- | ||
|
||
In Go applications, panics can occur during runtime when something unexpected happens. This guide explains how to handle panics both in general Go code and specifically in your Wails application. | ||
|
||
## Understanding Panics in Go | ||
|
||
Before diving into Wails-specific panic handling, it's essential to understand how panics work in Go: | ||
|
||
1. Panics are for unrecoverable errors that shouldn't happen during normal operation | ||
2. When a panic occurs in a goroutine, only that goroutine is affected | ||
3. Panics can be recovered using `defer` and `recover()` | ||
|
||
Here's a basic example of panic handling in Go: | ||
|
||
```go | ||
func doSomething() { | ||
// Deferred functions run even when a panic occurs | ||
defer func() { | ||
if r := recover(); r != nil { | ||
fmt.Printf("Recovered from panic: %v\n", r) | ||
} | ||
}() | ||
|
||
// Your code that might panic | ||
panic("something went wrong") | ||
} | ||
``` | ||
|
||
For more detailed information about panic and recover in Go, see the [Go Blog: Defer, Panic, and Recover](https://go.dev/blog/defer-panic-and-recover). | ||
|
||
## Panic Handling in Wails | ||
|
||
Wails automatically handles panics that occur in your Service methods when they are called from the frontend. This means you don't need to add panic recovery to these methods - Wails will catch the panic and process it through your configured panic handler. | ||
|
||
The panic handler is specifically designed to catch: | ||
- Panics in bound service methods called from the frontend | ||
- Internal panics from the Wails runtime | ||
|
||
For other scenarios, such as background goroutines or standalone Go code, you should handle panics yourself using Go's standard panic recovery mechanisms. | ||
|
||
## The PanicDetails Struct | ||
|
||
When a panic occurs, Wails captures important information about the panic in a `PanicDetails` struct: | ||
|
||
```go | ||
type PanicDetails struct { | ||
StackTrace string // The stack trace of where the panic occurred. Potentially trimmed to provide more context | ||
Error error // The error that caused the panic | ||
Time time.Time // The time when the panic occurred | ||
FullStackTrace string // The complete stack trace including runtime frames | ||
} | ||
``` | ||
|
||
This structure provides comprehensive information about the panic: | ||
- `StackTrace`: A formatted string showing the call stack that led to the panic | ||
- `Error`: The actual error or panic message | ||
- `Time`: The exact time when the panic occurred | ||
- `FullStackTrace`: The complete stack trace including runtime frames | ||
|
||
:::note[Panics in Service Code] | ||
|
||
When panics are caught in your Service code after being called from the frontend, the stack trace is trimmed to focus on exactly where in your code the panic occurred. | ||
If you want to see the full stack trace, you can use the `FullStackTrace` field. | ||
|
||
::: | ||
|
||
## Default Panic Handler | ||
|
||
If you don't specify a custom panic handler, Wails will use its default handler which outputs error information in a formatted log message. For example: | ||
|
||
``` | ||
Jan 16 21:18:05.649 ERR panic error: oh no! something went wrong deep in my service! :( | ||
main.(*WindowService).call2 | ||
at E:/wails/v3/examples/panic-handling/main.go:24 | ||
main.(*WindowService).call1 | ||
at E:/wails/v3/examples/panic-handling/main.go:20 | ||
main.(*WindowService).GeneratePanic | ||
at E:/wails/v3/examples/panic-handling/main.go:16 | ||
``` | ||
|
||
## Custom Panic Handler | ||
|
||
You can implement your own panic handler by setting the `PanicHandler` option when creating your application. Here's an example: | ||
|
||
```go | ||
app := application.New(application.Options{ | ||
Name: "My App", | ||
PanicHandler: func(panicDetails *application.PanicDetails) { | ||
fmt.Printf("*** Custom Panic Handler ***\n") | ||
fmt.Printf("Time: %s\n", panicDetails.Time) | ||
fmt.Printf("Error: %s\n", panicDetails.Error) | ||
fmt.Printf("Stacktrace: %s\n", panicDetails.StackTrace) | ||
fmt.Printf("Full Stacktrace: %s\n", panicDetails.FullStackTrace) | ||
|
||
// You could also: | ||
// - Log to a file | ||
// - Send to a crash reporting service | ||
// - Show a user-friendly error dialog | ||
// - Attempt to recover or restart the application | ||
}, | ||
}) | ||
``` | ||
|
||
For a complete working example of panic handling in a Wails application, see the panic-handling example in `v3/examples/panic-handling`. | ||
|
||
## Final Notes | ||
|
||
Remember that the Wails panic handler is specifically for managing panics in bound methods and internal runtime errors. For other parts of your application, you should use Go's standard error handling patterns and panic recovery mechanisms where appropriate. As with all Go applications, it's better to prevent panics through proper error handling where possible. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Panic Handling Example | ||
|
||
This example is a demonstration of how to handle panics in your application. | ||
|
||
## Running the example | ||
|
||
To run the example, simply run the following command: | ||
|
||
```bash | ||
go run . | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Window Call Demo</title> | ||
<style> | ||
body { | ||
color: white; | ||
} | ||
</style> | ||
<script src="/wails/runtime.js" type="module"></script> | ||
<script> | ||
async function callBinding(name, ...params) { | ||
return wails.Call.ByName(name, ...params) | ||
} | ||
</script> | ||
</head> | ||
<body> | ||
<button onclick="panic()">Create a panic</button> | ||
<script> | ||
async function panic() { | ||
await callBinding('main.WindowService.GeneratePanic') | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package main | ||
|
||
import ( | ||
"embed" | ||
"fmt" | ||
"github.com/wailsapp/wails/v3/pkg/application" | ||
"log" | ||
) | ||
|
||
//go:embed assets/* | ||
var assets embed.FS | ||
|
||
type WindowService struct{} | ||
|
||
func (s *WindowService) GeneratePanic() { | ||
s.call1() | ||
} | ||
|
||
func (s *WindowService) call1() { | ||
s.call2() | ||
} | ||
|
||
func (s *WindowService) call2() { | ||
panic("oh no! something went wrong deep in my service! :(") | ||
} | ||
|
||
// ============================================== | ||
|
||
func main() { | ||
app := application.New(application.Options{ | ||
Name: "Panic Handler Demo", | ||
Description: "A demo of Handling Panics", | ||
Assets: application.AssetOptions{ | ||
Handler: application.BundledAssetFileServer(assets), | ||
}, | ||
Mac: application.MacOptions{ | ||
ApplicationShouldTerminateAfterLastWindowClosed: false, | ||
}, | ||
Services: []application.Service{ | ||
application.NewService(&WindowService{}), | ||
}, | ||
PanicHandler: func(panicDetails *application.PanicDetails) { | ||
fmt.Printf("*** There was a panic! ***\n") | ||
fmt.Printf("Time: %s\n", panicDetails.Time) | ||
fmt.Printf("Error: %s\n", panicDetails.Error) | ||
fmt.Printf("Stacktrace: %s\n", panicDetails.StackTrace) | ||
}, | ||
}) | ||
|
||
app.NewWebviewWindow(). | ||
SetTitle("WebviewWindow 1"). | ||
Show() | ||
|
||
err := app.Run() | ||
|
||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.