mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-26 17:59:29 +00:00
rpc: pre-encode JSON-RPC error responses at creation time
This commit is contained in:
parent
d620f9f96a
commit
4a6e13623a
4 changed files with 31 additions and 25 deletions
|
|
@ -364,7 +364,7 @@ func (c *Client) CallContext(ctx context.Context, result interface{}, method str
|
|||
resp := batchresp[0]
|
||||
switch {
|
||||
case resp.Error != nil:
|
||||
return resp.Error
|
||||
return resp.jsonErr()
|
||||
case len(resp.Result) == 0:
|
||||
return ErrNoResult
|
||||
default:
|
||||
|
|
@ -449,7 +449,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
|
|||
elem := &b[index]
|
||||
switch {
|
||||
case resp.Error != nil:
|
||||
elem.Error = resp.Error
|
||||
elem.Error = resp.jsonErr()
|
||||
case resp.Result == nil:
|
||||
elem.Error = ErrNoResult
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ func (h *handler) handleBatch(msgs []*jsonrpcMessage) {
|
|||
resp := h.handleCallMsg(cp, msg)
|
||||
callBuffer.pushResponse(resp)
|
||||
if resp != nil && h.batchResponseMaxSize != 0 {
|
||||
responseBytes += len(resp.Result)
|
||||
responseBytes += len(resp.Result) + len(resp.Error)
|
||||
if responseBytes > h.batchResponseMaxSize {
|
||||
err := &internalServerError{errcodeResponseTooLarge, errMsgResponseTooLarge}
|
||||
callBuffer.respondWithError(cp.ctx, h.conn, err)
|
||||
|
|
@ -415,7 +415,7 @@ func (h *handler) handleResponses(batch []*jsonrpcMessage, handleCall func(*json
|
|||
// the op.resp channel.
|
||||
if op.sub != nil {
|
||||
if msg.Error != nil {
|
||||
op.err = msg.Error
|
||||
op.err = msg.jsonErr()
|
||||
} else {
|
||||
op.err = json.Unmarshal(msg.Result, &op.sub.subid)
|
||||
if op.err == nil {
|
||||
|
|
@ -481,9 +481,10 @@ func (h *handler) handleCallMsg(ctx *callProc, msg *jsonrpcMessage) *jsonrpcMess
|
|||
var logctx []any
|
||||
logctx = append(logctx, "reqid", idForLog{msg.ID}, "duration", time.Since(start))
|
||||
if resp.Error != nil {
|
||||
logctx = append(logctx, "err", resp.Error.Message)
|
||||
if resp.Error.Data != nil {
|
||||
logctx = append(logctx, "errdata", formatErrorData(resp.Error.Data))
|
||||
je := resp.jsonErr()
|
||||
logctx = append(logctx, "err", je.Message)
|
||||
if je.Data != nil {
|
||||
logctx = append(logctx, "errdata", formatErrorData(je.Data))
|
||||
}
|
||||
h.log.Warn("Served "+msg.Method, logctx...)
|
||||
} else {
|
||||
|
|
@ -550,7 +551,7 @@ func (h *handler) handleCall(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage
|
|||
answer := h.runMethod(rctx, msg, callb, args)
|
||||
var rErr error
|
||||
if answer.Error != nil {
|
||||
rErr = errors.New(answer.Error.Message)
|
||||
rErr = errors.New(answer.jsonErr().Message)
|
||||
}
|
||||
rSpanEnd(&rErr)
|
||||
|
||||
|
|
@ -623,7 +624,7 @@ func (h *handler) runMethod(ctx context.Context, msg *jsonrpcMessage, callb *cal
|
|||
_, _, spanEnd := telemetry.StartSpanWithTracer(ctx, h.tracer(), "rpc.encodeJSONResponse", attributes...)
|
||||
response := msg.response(result)
|
||||
if response.Error != nil {
|
||||
err = errors.New(response.Error.Message)
|
||||
err = errors.New(response.jsonErr().Message)
|
||||
}
|
||||
spanEnd(&err)
|
||||
return response
|
||||
|
|
|
|||
35
rpc/json.go
35
rpc/json.go
|
|
@ -60,7 +60,7 @@ type jsonrpcMessage struct {
|
|||
ID json.RawMessage `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Params json.RawMessage `json:"params,omitempty"`
|
||||
Error *jsonError `json:"error,omitempty"`
|
||||
Error json.RawMessage `json:"error,omitempty"`
|
||||
Result json.RawMessage `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -108,6 +108,16 @@ func (msg *jsonrpcMessage) errorResponse(err error) *jsonrpcMessage {
|
|||
return resp
|
||||
}
|
||||
|
||||
// jsonErr decodes the Error field into a jsonError struct.
|
||||
func (msg *jsonrpcMessage) jsonErr() *jsonError {
|
||||
if msg.Error == nil {
|
||||
return nil
|
||||
}
|
||||
je := new(jsonError)
|
||||
json.Unmarshal(msg.Error, je)
|
||||
return je
|
||||
}
|
||||
|
||||
func (msg *jsonrpcMessage) response(result interface{}) *jsonrpcMessage {
|
||||
var (
|
||||
enc []byte
|
||||
|
|
@ -125,19 +135,18 @@ func (msg *jsonrpcMessage) response(result interface{}) *jsonrpcMessage {
|
|||
}
|
||||
|
||||
func errorMessage(err error) *jsonrpcMessage {
|
||||
msg := &jsonrpcMessage{Version: vsn, ID: null, Error: &jsonError{
|
||||
je := &jsonError{
|
||||
Code: errcodeDefault,
|
||||
Message: err.Error(),
|
||||
}}
|
||||
ec, ok := err.(Error)
|
||||
if ok {
|
||||
msg.Error.Code = ec.ErrorCode()
|
||||
}
|
||||
de, ok := err.(DataError)
|
||||
if ok {
|
||||
msg.Error.Data = de.ErrorData()
|
||||
if ec, ok := err.(Error); ok {
|
||||
je.Code = ec.ErrorCode()
|
||||
}
|
||||
return msg
|
||||
if de, ok := err.(DataError); ok {
|
||||
je.Data = de.ErrorData()
|
||||
}
|
||||
enc, _ := json.Marshal(je)
|
||||
return &jsonrpcMessage{Version: vsn, ID: null, Error: enc}
|
||||
}
|
||||
|
||||
type jsonError struct {
|
||||
|
|
@ -248,12 +257,8 @@ func writeMessage(w io.Writer, msg *jsonrpcMessage) error {
|
|||
buf = append(buf, msg.Params...)
|
||||
}
|
||||
if msg.Error != nil {
|
||||
errBytes, err := json.Marshal(msg.Error)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf = append(buf, `,"error":`...)
|
||||
buf = append(buf, errBytes...)
|
||||
buf = append(buf, msg.Error...)
|
||||
}
|
||||
if msg.Result != nil {
|
||||
buf = append(buf, `,"result":`...)
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ func readAndValidateMessage(in *json.Decoder) (*subConfirmation, *subscriptionRe
|
|||
case msg.isResponse():
|
||||
var c subConfirmation
|
||||
if msg.Error != nil {
|
||||
return nil, nil, msg.Error
|
||||
return nil, nil, msg.jsonErr()
|
||||
} else if err := json.Unmarshal(msg.Result, &c.subid); err != nil {
|
||||
return nil, nil, fmt.Errorf("invalid response: %v", err)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue