Skip to content

Commit

Permalink
Remove the DataErrorf constructor.
Browse files Browse the repository at this point in the history
Make Errorf return the *jrpc2.Error value concretely, and equip that type with
a WithData method. This permits the reuse of base errors with different data.
  • Loading branch information
creachadair committed Oct 14, 2021
1 parent 55fbb9b commit 37bcf3b
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 19 deletions.
2 changes: 1 addition & 1 deletion base.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ func (j *jmessage) parseJSON(data []byte) error {

// Report an error for extraneous fields.
if j.err == nil && len(extra) != 0 {
j.err = DataErrorf(code.InvalidRequest, extra, "extra fields in request")
j.err = Errorf(code.InvalidRequest, "extra fields in request").WithData(extra)
}
return nil
}
Expand Down
30 changes: 14 additions & 16 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ func (e Error) MarshalJSON() ([]byte, error) {
return json.Marshal(jerror{C: int32(e.Code), M: e.Message, D: e.Data})
}

// WithData marshals v as JSON and constructs a copy of e whose Data field
// includes the result. If v == nil or if marshaling v fails, e is returned
// without modification.
func (e *Error) WithData(v interface{}) *Error {
if v == nil {
return e
} else if data, err := json.Marshal(v); err == nil {
return &Error{Code: e.Code, Message: e.Message, Data: data}
}
return e
}

// UnmarshalJSON implements the json.Unmarshaler interface for Error values.
func (e *Error) UnmarshalJSON(data []byte) error {
var v jerror
Expand Down Expand Up @@ -62,20 +74,6 @@ var ErrConnClosed = errors.New("client connection is closed")

// Errorf returns an error value of concrete type *Error having the specified
// code and formatted message string.
// It is shorthand for DataErrorf(code, nil, msg, args...)
func Errorf(code code.Code, msg string, args ...interface{}) error {
return DataErrorf(code, nil, msg, args...)
}

// DataErrorf returns an error value of concrete type *Error having the
// specified code, error data, and formatted message string.
// If v == nil this behaves identically to Errorf(code, msg, args...).
func DataErrorf(code code.Code, v interface{}, msg string, args ...interface{}) error {
e := &Error{Code: code, Message: fmt.Sprintf(msg, args...)}
if v != nil {
if data, err := json.Marshal(v); err == nil {
e.Data = data
}
}
return e
func Errorf(code code.Code, msg string, args ...interface{}) *Error {
return &Error{Code: code, Message: fmt.Sprintf(msg, args...)}
}
2 changes: 1 addition & 1 deletion internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func TestMarshalResponse(t *testing.T) {
}{
{"", nil, "", `{"jsonrpc":"2.0"}`},
{"null", nil, "", `{"jsonrpc":"2.0","id":null}`},
{"123", Errorf(code.ParseError, "failed").(*Error), "",
{"123", Errorf(code.ParseError, "failed"), "",
`{"jsonrpc":"2.0","id":123,"error":{"code":-32700,"message":"failed"}}`},
{"456", nil, `{"ok":true,"values":[4,5,6]}`,
`{"jsonrpc":"2.0","id":456,"result":{"ok":true,"values":[4,5,6]}}`},
Expand Down
2 changes: 1 addition & 1 deletion jrpc2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ func TestError_withData(t *testing.T) {
const errMessage = "error thingy"
loc := server.NewLocal(handler.Map{
"Err": handler.New(func(_ context.Context) (int, error) {
return 17, jrpc2.DataErrorf(errCode, json.RawMessage(errData), errMessage)
return 17, jrpc2.Errorf(errCode, errMessage).WithData(json.RawMessage(errData))
}),
"Push": handler.New(func(ctx context.Context) (bool, error) {
return false, jrpc2.ServerFromContext(ctx).Notify(ctx, "PushBack", nil)
Expand Down

0 comments on commit 37bcf3b

Please sign in to comment.