rpc: support wrapped errors and code-based Is for jsonError#649
rpc: support wrapped errors and code-based Is for jsonError#649pmikolajczyk41 wants to merge 1 commit into
Conversation
| ec, ok := err.(Error) | ||
| if ok { | ||
| var ec Error | ||
| if errors.As(err, &ec) { |
There was a problem hiding this comment.
It is annoying that the upstream geth doesn't use error.As already here.
But changing our fork like this can hurt us down the line, when updating the fork with upstream geth.
Also, not sure if this will negatively affect native geth APIs.
So avoiding changes like this in geth, if the alternative is not too complicated, is advisable.
An alternative is, the server side, e.g. execution/rpcserver.Server. DigestMessage, checks if the error to be returned has a wrapped RPCError through error.As. If so then it returns a plain RPCError, with the same error code of the wrapped RPCError, and error message equal to the original error.
There was a problem hiding this comment.
proposed this change to upstream: ethereum/go-ethereum#34886
| // This allows errors.Is(receivedErr, sentinel) to work on the client side | ||
| // when receivedErr is a jsonError reconstructed from the wire and sentinel | ||
| // is any error that exposes an ErrorCode() int method. | ||
| func (err *jsonError) Is(target error) bool { |
There was a problem hiding this comment.
This one can be avoided if the client side, e.g. execution/rpcclient.Client.DigestMessage, always tries to build a RPCError, from the error returned by the server, using the same error code and message provided by the error returned by the server.
RPCError already has a Is func.
errorMessagepreviously cast err directly torpc.Error/DataError, which missed errors wrapped withfmt.Errorf("%w", ...). Switch toerrors.Asso the code and data are extracted correctly from wrapped errors.(*jsonError).Isso thaterrors.Is(receivedErr, sentinel)works on the client side whenreceivedErris ajsonErrorreconstructed from the wire. Matching is by error code: if the sentinel implementsErrorCode() int, the codes are compared. This avoids the need for string-based error reconstruction in callers.pulled in by OffchainLabs/nitro#4629