rpc: get error code/data from wrapped error#34886
Conversation
|
It's a little strange to extract the code and data separately. There could be a situation where one error in the nesting chain supplies the code, and another error supplies the data. For this reason, I think it is more correct to require that these methods be implemented by the top-level error. It is usually no problem to ensure this. |
|
@fjl I agree that extracting them is a little strange (in general, the situation where two different errors in chain provide this data independently is just strange) but what about mixing the two approaches and using |
|
Maybe that could be OK. I'm just curious what this provides to you. |
|
From reading the issue, you want to do err := client.Call(&r, "method", ...)
if errors.Is(err, api.ErrSomething) {
...
}and it's supposed to match on the code. This can be done by implementing the |
|
yes, exactly; originally my changes to geth (OffchainLabs/go-ethereum#649) contained also the |
|
No the type codedError struct{
code int
message string
}
func (ce codedError) Error() string { return ce.message }
func (ce codedError) ErrorCode() int { return ce.code }
func (ce codedError) Is(err error) bool {
// As per documentation in package "errors",
// An Is method should only shallowly compare err and the target and not call Unwrap.
rpcerr, ok := err.(rpc.Error)
return ok && rpcerr.ErrorCode() == ce.code
}
var ErrSomething = codedError{100, "something"} |
|
but doesn't implementing |
|
I think it's not appropriate because |
|
fair enough; thank you therefore for this discussion, I will go with the suggested approach |
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. This turns out to be very useful in client-server communication based on the geth'srpcpackage (see e.g. OffchainLabs/nitro#4629).