Skip to content

Commit 0a3551c

Browse files
committed
fix: struct error
1 parent 6f0cb50 commit 0a3551c

File tree

8 files changed

+97
-7
lines changed

8 files changed

+97
-7
lines changed

error.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ func NewError(err error) *Error {
3434

3535
// retrieve error details
3636
errType := reflect.TypeOf(err)
37+
errElem := errType
38+
if errType.Kind() == reflect.Ptr {
39+
errElem = errType.Elem()
40+
}
3741

3842
inst := &Error{
3943
Msg: err.Error(),
4044
Type: errType.String(),
41-
Pkg: errType.Elem().PkgPath(),
45+
Pkg: errElem.PkgPath(),
4246
Data: err,
4347
}
4448

@@ -80,9 +84,9 @@ func (e *Error) Format(s fmt.State, verb rune) {
8084
switch verb {
8185
case 'v':
8286
if s.Flag('+') {
83-
fmt.Fprintf(s, "%s.(%s)\n", e.Pkg, e.Type)
87+
_, _ = fmt.Fprintf(s, "%s.(%s)\n", e.Pkg, e.Type)
8488
if e.Data != nil {
85-
fmt.Fprintf(s, "Data: %v\n", e.Data)
89+
_, _ = fmt.Fprintf(s, "Data: %v\n", e.Data)
8690
}
8791
}
8892
fallthrough
@@ -106,10 +110,14 @@ func (e *Error) Is(err error) bool {
106110
}
107111

108112
errType := reflect.TypeOf(err)
113+
errElem := errType
114+
if errType.Kind() == reflect.Ptr {
115+
errElem = errType.Elem()
116+
}
109117

110118
if e.Msg == err.Error() &&
111119
errType.String() == e.Type &&
112-
errType.Elem().PkgPath() == e.Pkg {
120+
errElem.PkgPath() == e.Pkg {
113121
return true
114122
}
115123

example/errors/handler/backend/handler.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ import (
1010

1111
type (
1212
ScalarError string
13+
StructError struct {
14+
Msg string
15+
Map map[string]string
16+
Slice []string
17+
Struct struct {
18+
A string
19+
}
20+
}
1321
CustomError struct {
1422
Msg string
1523
Map map[string]string
@@ -33,6 +41,19 @@ func (e *ScalarError) Error() string {
3341
return string(*e)
3442
}
3543

44+
func NewStructError(msg string) StructError {
45+
return StructError{
46+
Msg: msg,
47+
Map: map[string]string{"a": "b"},
48+
Slice: []string{"a", "b"},
49+
Struct: struct{ A string }{A: "b"},
50+
}
51+
}
52+
53+
func (e StructError) Error() string {
54+
return e.Msg
55+
}
56+
3657
func NewCustomError(msg string) *CustomError {
3758
return &CustomError{
3859
Msg: msg,
@@ -86,6 +107,10 @@ func (h *Handler) TypedError(w http.ResponseWriter, r *http.Request) (e error) {
86107
return ErrTyped
87108
}
88109

110+
func (h *Handler) StructError(w http.ResponseWriter, r *http.Request) (e error) {
111+
return NewStructError("struct error")
112+
}
113+
89114
func (h *Handler) ScalarError(w http.ResponseWriter, r *http.Request) (e error) {
90115
return NewScalarError(ScalarErrorOne)
91116
}

example/errors/main.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,28 @@ func call() {
147147
}
148148
}
149149

150+
{
151+
fmt.Println("--- StructError ----------------")
152+
var structErr backend.StructError
153+
var gotsrpcErr *gotsrpc.Error
154+
serviceErr, err := c.StructError(ctx)
155+
if err != nil {
156+
panic("client error should be nil")
157+
} else if serviceErr == nil {
158+
panic("service error should not be nil")
159+
} else if serviceErr != nil {
160+
fmt.Printf("%s\n", serviceErr)
161+
fmt.Printf("%q\n", serviceErr)
162+
fmt.Printf("%+v\n", serviceErr)
163+
}
164+
if errors.As(serviceErr, &gotsrpcErr) {
165+
fmt.Println(gotsrpcErr)
166+
}
167+
if errors.As(serviceErr, &structErr) {
168+
fmt.Println(structErr)
169+
}
170+
}
171+
150172
{
151173
fmt.Println("--- CustomError ----------------")
152174
var customErr *backend.CustomError

example/errors/service/backend/gotsrpc_gen.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/errors/service/backend/gotsrpcclient_gen.go

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/errors/service/backend/service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Service interface {
5454
Scalar(w http.ResponseWriter, r *http.Request) (e *ScalarError)
5555
MultiScalar(w http.ResponseWriter, r *http.Request) (e *MultiScalar)
5656
Struct(w http.ResponseWriter, r *http.Request) (e *StructError)
57+
StructError(w http.ResponseWriter, r *http.Request) (e error)
5758
TypedError(w http.ResponseWriter, r *http.Request) (e error)
5859
ScalarError(w http.ResponseWriter, r *http.Request) (e error)
5960
CustomError(w http.ResponseWriter, r *http.Request) (e error)

gotsrpc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func Reply(response []interface{}, stats *CallStats, r *http.Request, w http.Res
120120
if len(response) > 0 {
121121
errResp := response[len(response)-1]
122122
if v, ok := errResp.(error); ok && v != nil {
123-
if !reflect.ValueOf(v).IsNil() {
123+
if !reflect.ValueOf(v).IsZero() {
124124
stats.ErrorCode = 1
125125
stats.ErrorType = fmt.Sprintf("%T", v)
126126
stats.ErrorMessage = v.Error()

transport.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var msgpackClientHandle = &clientHandle{
3333
beforeEncodeReply: func(resp *[]interface{}) error {
3434
for k, v := range *resp {
3535
if e, ok := v.(error); ok {
36-
if r := reflect.ValueOf(e); !r.IsNil() {
36+
if r := reflect.ValueOf(e); !r.IsZero() {
3737
(*resp)[k] = NewError(e)
3838
}
3939
}
@@ -43,7 +43,11 @@ var msgpackClientHandle = &clientHandle{
4343
beforeDecodeReply: func(reply []interface{}) ([]interface{}, error) {
4444
ret := make([]interface{}, len(reply))
4545
for k, v := range reply {
46-
if reflect.TypeOf(v).Elem().Implements(errorType) {
46+
val := reflect.TypeOf(v)
47+
if val.Kind() == reflect.Ptr {
48+
val = val.Elem()
49+
}
50+
if val.Implements(errorType) {
4751
var e *Error
4852
ret[k] = e
4953
} else {

0 commit comments

Comments
 (0)