Skip to content

Commit

Permalink
feat: add WrapError
Browse files Browse the repository at this point in the history
  • Loading branch information
powerman committed Apr 22, 2020
1 parent 6776687 commit e9498a9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
24 changes: 24 additions & 0 deletions jsonrpc2/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package jsonrpc2
import (
"encoding/json"
"fmt"
"io"
"net/rpc"
"strings"
)

Expand Down Expand Up @@ -90,3 +92,25 @@ func (e *Error) Error() string {
}
return string(buf)
}

type wrapError struct {
err *Error
}

// WrapError handles any error returned by Client.Call() by wrapping Error
// returned by ServerError or returning non-ServerError errors as is.
// Wrapped Error is stringified to "<code> <message>" instead of JSON.
func WrapError(err error) error {
if err == nil || err == rpc.ErrShutdown || err == io.ErrUnexpectedEOF {
return err
}
return wrapError{err: ServerError(err)}
}

func (e wrapError) Error() string {
return fmt.Sprintf("%d %s", e.err.Code, e.err.Message)
}

func (e wrapError) Unwrap() error {
return e.err
}
27 changes: 27 additions & 0 deletions jsonrpc2/errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package jsonrpc2

import (
"io"
"net/rpc"
"testing"
)

func TestWrapError(t *testing.T) {
tests := []struct {
err error
}{
{nil},
{rpc.ErrShutdown},
{io.ErrUnexpectedEOF},
}
for _, tc := range tests {
tc := tc
t.Run("", func(t *testing.T) {
err := WrapError(tc.err)
if err != tc.err {
t.Errorf("got %v, want %v", err, tc.err)
}
})
}

}
20 changes: 7 additions & 13 deletions jsonrpc2/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,14 @@ func Example() {
clientHTTP.Call("ExampleSvc.FullName3", NameArg{"First", "Last"}, nil)

// Correct error handling.
err = clientTCP.Call("ExampleSvc.Err1", nil, nil)
if err == rpc.ErrShutdown || err == io.ErrUnexpectedEOF {
fmt.Printf("Err1(): %q\n", err)
} else if err != nil {
rpcerr := jsonrpc2.ServerError(err)
fmt.Printf("Err1(): code=%d msg=%q data=%v\n", rpcerr.Code, rpcerr.Message, rpcerr.Data)
}
err = jsonrpc2.WrapError(clientTCP.Call("ExampleSvc.Err1", nil, nil))
fmt.Printf("Err1(): %q\n", err)

err = clientCustomHTTP.Call("ExampleSvc.Err2", nil, nil)
if err == rpc.ErrShutdown || err == io.ErrUnexpectedEOF {
fmt.Printf("Err2(): %q\n", err)
} else if err != nil {
rpcerr := jsonrpc2.ServerError(err)
err = jsonrpc2.WrapError(clientCustomHTTP.Call("ExampleSvc.Err2", nil, nil))
if rpcerr := new(jsonrpc2.Error); errors.As(err, &rpcerr) {
fmt.Printf("Err2(): code=%d msg=%q data=%v\n", rpcerr.Code, rpcerr.Message, rpcerr.Data)
} else if err != nil {
fmt.Printf("Err2(): %q\n", err)
}

err = clientHTTP.Call("ExampleSvc.Err3", nil, nil)
Expand All @@ -195,7 +189,7 @@ func Example() {
// MapLen({a:10,b:20,c:30})=3
// FullName2(): Remote IP is 127.0.0.1
// FullName3(): Remote IP is 127.0.0.1
// Err1(): code=-32000 msg="some issue" data=<nil>
// Err1(): "-32000 some issue"
// Err2(): code=-32603 msg="bad HTTP Status: 415 Unsupported Media Type" data=<nil>
// Err3(): code=42 msg="some issue" data=[one two]
}

0 comments on commit e9498a9

Please sign in to comment.