diff --git a/jsonrpc2.go b/jsonrpc2.go index 17e1a59..46273bc 100644 --- a/jsonrpc2.go +++ b/jsonrpc2.go @@ -29,10 +29,10 @@ type JSONRPC2 interface { type Error struct { Code int64 `json:"code"` Message string `json:"message"` - Data *json.RawMessage `json:"data"` + Data *json.RawMessage `json:"data,omitempty"` } -// SetError sets e.Error to the JSON representation of v. If JSON +// SetError sets e.Data to the JSON representation of v. If JSON // marshaling fails, it panics. func (e *Error) SetError(v interface{}) { b, err := json.Marshal(v) diff --git a/jsonrpc2_test.go b/jsonrpc2_test.go index 1a73744..dcc2679 100644 --- a/jsonrpc2_test.go +++ b/jsonrpc2_test.go @@ -18,6 +18,65 @@ import ( websocketjsonrpc2 "github.com/sourcegraph/jsonrpc2/websocket" ) +func TestError_MarshalJSON(t *testing.T) { + tests := []struct { + name string + setError func(err *jsonrpc2.Error) + want string + }{ + { + name: "Data == nil", + want: `{"code":-32603,"message":"Internal error"}`, + }, + { + name: "Error.SetError(nil)", + setError: func(err *jsonrpc2.Error) { + err.SetError(nil) + }, + want: `{"code":-32603,"message":"Internal error","data":null}`, + }, + { + name: "Error.SetError(0)", + setError: func(err *jsonrpc2.Error) { + err.SetError(0) + }, + want: `{"code":-32603,"message":"Internal error","data":0}`, + }, + { + name: `Error.SetError("")`, + setError: func(err *jsonrpc2.Error) { + err.SetError("") + }, + want: `{"code":-32603,"message":"Internal error","data":""}`, + }, + { + name: `Error.SetError(false)`, + setError: func(err *jsonrpc2.Error) { + err.SetError(false) + }, + want: `{"code":-32603,"message":"Internal error","data":false}`, + }, + } + + for _, test := range tests { + e := &jsonrpc2.Error{ + Code: jsonrpc2.CodeInternalError, + Message: "Internal error", + } + if test.setError != nil { + test.setError(e) + } + b, err := json.Marshal(e) + if err != nil { + t.Error(err) + } + got := string(b) + if got != test.want { + t.Fatalf("%s: got %q, want %q", test.name, got, test.want) + } + } +} + // testHandlerA is the "server" handler. type testHandlerA struct{ t *testing.T }