diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go
index 7cdc627f1..2e04f448b 100644
--- a/v2/internal/app/app_dev.go
+++ b/v2/internal/app/app_dev.go
@@ -213,7 +213,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)
+ messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter)
// 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 2dfad6015..5b847260c 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)
+ messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter)
appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
eventHandler.AddFrontend(appFrontend)
diff --git a/v2/internal/frontend/dispatcher/calls.go b/v2/internal/frontend/dispatcher/calls.go
index ef19c6030..491d17fe2 100644
--- a/v2/internal/frontend/dispatcher/calls.go
+++ b/v2/internal/frontend/dispatcher/calls.go
@@ -3,8 +3,9 @@ package dispatcher
import (
"encoding/json"
"fmt"
- "github.com/wailsapp/wails/v2/internal/frontend"
"strings"
+
+ "github.com/wailsapp/wails/v2/internal/frontend"
)
type callMessage struct {
@@ -49,7 +50,12 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend
CallbackID: payload.CallbackID,
}
if err != nil {
- callbackMessage.Err = err.Error()
+ // Use the error formatter if one was provided
+ if d.errfmt != nil {
+ callbackMessage.Err = d.errfmt(err)
+ } else {
+ callbackMessage.Err = err.Error()
+ }
} else {
callbackMessage.Result = result
}
@@ -66,7 +72,7 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend
// CallbackMessage defines a message that contains the result of a call
type CallbackMessage struct {
Result interface{} `json:"result"`
- Err string `json:"error"`
+ Err any `json:"error"`
CallbackID string `json:"callbackid"`
}
diff --git a/v2/internal/frontend/dispatcher/dispatcher.go b/v2/internal/frontend/dispatcher/dispatcher.go
index 44a8886e5..56092d370 100644
--- a/v2/internal/frontend/dispatcher/dispatcher.go
+++ b/v2/internal/frontend/dispatcher/dispatcher.go
@@ -7,6 +7,7 @@ import (
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/logger"
+ "github.com/wailsapp/wails/v2/pkg/options"
)
type Dispatcher struct {
@@ -15,15 +16,17 @@ type Dispatcher struct {
events frontend.Events
bindingsDB *binding.DB
ctx context.Context
+ errfmt options.ErrorFormatter
}
-func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events) *Dispatcher {
+func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events, errfmt options.ErrorFormatter) *Dispatcher {
return &Dispatcher{
log: log,
bindings: bindings,
events: events,
bindingsDB: bindings.DB(),
ctx: ctx,
+ errfmt: errfmt,
}
}
diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go
index 1562a7dff..2fbcbc8b8 100644
--- a/v2/pkg/options/options.go
+++ b/v2/pkg/options/options.go
@@ -64,6 +64,9 @@ type App struct {
Bind []interface{}
WindowStartState WindowStartState
+ // ErrorFormatter overrides the formatting of errors returned by backend methods
+ ErrorFormatter ErrorFormatter
+
// CSS property to test for draggable elements. Default "--wails-draggable"
CSSDragProperty string
@@ -90,6 +93,8 @@ type App struct {
Debug Debug
}
+type ErrorFormatter func(error) any
+
type RGBA struct {
R uint8 `json:"r"`
G uint8 `json:"g"`
diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx
index 62ffffe1e..5eb5f0972 100644
--- a/website/docs/reference/options.mdx
+++ b/website/docs/reference/options.mdx
@@ -58,6 +58,7 @@ func main() {
Bind: []interface{}{
app,
},
+ ErrorFormatter: func(err error) any { return err.Error() },
Windows: &windows.Options{
WebviewIsTransparent: false,
WindowIsTranslucent: false,
@@ -477,6 +478,14 @@ A slice of struct instances defining methods that need to be bound to the fronte
Name: Bind
Type: `[]interface{}`
+### ErrorFormatter
+
+A function that determines how errors are formatted when returned by a JS-to-Go
+method call. The returned value will be marshalled as JSON.
+
+Name: ErrorFormatter
+Type: `func (error) any`
+
### Windows
This defines [Windows specific options](#windows).
diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx
index f82f2fd53..632b8c69b 100644
--- a/website/src/pages/changelog.mdx
+++ b/website/src/pages/changelog.mdx
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725)
- Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733)
- Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748)
+- Added custom error formatting to allow passing structured errors back to the frontend.
### Changed