From f3e0a7e7aec9283716ec1010fc89d62b007722c7 Mon Sep 17 00:00:00 2001 From: "Vojtech Vitek (golang.cz)" Date: Wed, 27 Sep 2023 15:31:04 +0200 Subject: [PATCH] Implement -errorStackTrace opt-in option (#41) The stack trace is reflect-compatible with: - github.com/pkg/errors - golang.org/x/xerrors - golang.org/x/exp/errors and thus can be inspected via reflect pkg by tools like: - https://github.com/getsentry/sentry-go - https://github.com/golang-cz/devslog - etc. --- README.md | 1 + errors.go.tmpl | 14 ++++++++++++++ imports.go.tmpl | 4 ++++ main.go.tmpl | 1 + 4 files changed, 20 insertions(+) diff --git a/README.md b/README.md index 4dfa35a..76076a4 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Change any of the following values by passing `-option="Value"` CLI flag to `web | `-types=false` | `true` | don't generate types | v0.13.0 | | `-json=jsoniter` | `"stdlib"` | use alternative json encoding package | v0.12.0 | | `-fixEmptyArrays` | `false` | force empty array `[]` instead of `null` in JSON (see Go [#27589][go27589]) | v0.13.0 | +| `-errorStackTrace` | `false` | enables error stack traces | v0.14.0 | | `-legacyErrors` | `false` | enable legacy errors (v0.10.0 or older) | v0.11.0 | Example: diff --git a/errors.go.tmpl b/errors.go.tmpl index eec597a..2bda47d 100644 --- a/errors.go.tmpl +++ b/errors.go.tmpl @@ -13,6 +13,11 @@ type WebRPCError struct { Cause string `json:"cause,omitempty"` HTTPStatus int `json:"status"` cause error + + {{- if $opts.errorStackTrace }} + {{- /* The below field is reflect-compatible with golang.org/x/xerrors.*/}} + frame struct { frames [3]uintptr } + {{- end}} } var _ error = WebRPCError{} @@ -44,9 +49,18 @@ func ErrorWithCause(rpcErr WebRPCError, cause error) WebRPCError { err := rpcErr err.cause = cause err.Cause = cause.Error() + {{- if $opts.errorStackTrace }} + runtime.Callers(1, err.frame.frames[:]) + {{- end}} return err } +{{ if $opts.errorStackTrace -}} +func (e WebRPCError) StackFrames() []uintptr { + return e.frame.frames[:] +} +{{- end }} + // Webrpc errors var ( {{- range $_, $error := $webrpcErrors}} diff --git a/imports.go.tmpl b/imports.go.tmpl index bbd2acc..5c23afc 100644 --- a/imports.go.tmpl +++ b/imports.go.tmpl @@ -13,6 +13,10 @@ {{- set $stdlibImports "encoding/json" "" -}} {{- end -}} +{{- if $opts.errorStackTrace }} + {{- set $stdlibImports "runtime" "" -}} +{{- end -}} + {{- if $opts.client }} {{- set $stdlibImports "bytes" "" -}} {{- set $stdlibImports "io" "" -}} diff --git a/main.go.tmpl b/main.go.tmpl index 4ddab9d..1aed6f3 100644 --- a/main.go.tmpl +++ b/main.go.tmpl @@ -9,6 +9,7 @@ {{- set $opts "json" (default .Opts.json "stdlib") -}} {{- set $opts "importTypesFrom" (default .Opts.importTypesFrom "" ) -}} {{- set $opts "fixEmptyArrays" (ternary (in .Opts.fixEmptyArrays "" "true") true false) -}} +{{- set $opts "errorStackTrace" (ternary (in .Opts.errorStackTrace "" "true") true false) -}} {{- set $opts "legacyErrors" (ternary (in .Opts.legacyErrors "" "true") true false) -}} {{- $typePrefix := (last (split "/" $opts.importTypesFrom)) -}}