82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package jsonrpc2
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
const (
|
|
// Invalid JSON was received by the server.
|
|
// An error occurred on the server while parsing the JSON text.
|
|
errCodeParse = -32700
|
|
|
|
// The JSON sent is not a valid Request object.
|
|
errCodeInvalidRequest = -32600
|
|
|
|
// The method does not exist / is not available.
|
|
errCodeMethodNotFound = -32601
|
|
|
|
// Invalid method parameter(s).
|
|
errCodeInvalidParams = -32602
|
|
|
|
// Reserved for implementation-defined server-errors.
|
|
errCodeServerError = -32000
|
|
)
|
|
|
|
// Error implements the error stuct type defined in the spec, as well as the go
|
|
// error interface and the `Is` method for the errors package. Note that the
|
|
// `Is` method will check both the type and Code of the given target in order to
|
|
// check same-ness.
|
|
type Error struct {
|
|
// Code is an identifier for the kind of error being returned. All
|
|
// application-defined error codes should be positive.
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Data any `json:"data,omitempty"`
|
|
}
|
|
|
|
// NewError returns an error with the given Code and formatted Message.
|
|
func NewError(code int, msgFmt string, msgArgs ...any) Error {
|
|
return Error{Code: code, Message: fmt.Sprintf(msgFmt, msgArgs...)}
|
|
}
|
|
|
|
// NewInvalidParamsError returns an error indicating that the provided
|
|
// parameters were invalid.
|
|
//
|
|
// Parameters are considered invalid if they could never possibly be valid in
|
|
// the format they were given and always indicate a bug in the caller. For
|
|
// example a timedate string in the wrong format.
|
|
//
|
|
// If a parameter is invalid due to the context it was used in, for example a
|
|
// wrong password, a specific error code should be used to indicate that to the
|
|
// caller.
|
|
func NewInvalidParamsError(msgFmt string, msgArgs ...any) Error {
|
|
return NewError(errCodeInvalidParams, msgFmt, msgArgs...)
|
|
}
|
|
|
|
func (e Error) Error() string {
|
|
buf := new(bytes.Buffer)
|
|
fmt.Fprintf(buf, "[%d] %s", e.Code, e.Message)
|
|
if e.Data != nil {
|
|
fmt.Fprint(buf, "\nExtra data: ")
|
|
if err := json.NewEncoder(buf).Encode(e.Data); err != nil {
|
|
panic(fmt.Sprintf("json encoding Error.Data %#v: %v", e.Data, err))
|
|
}
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
func (e Error) Is(target error) bool {
|
|
if tErr, ok := target.(Error); ok {
|
|
return tErr.Code == e.Code
|
|
}
|
|
return false
|
|
}
|
|
|
|
// WithData returns a copy of the Error with the Data file overwritten.
|
|
func (e Error) WithData(data any) Error {
|
|
e.Data = data
|
|
return e
|
|
}
|