accounts, console, internal, rpc: minor error interface cleanups
This commit is contained in:
parent
53508c5d46
commit
2d3ef53c53
|
@ -352,24 +352,27 @@ func newRevertError(result *core.ExecutionResult) *revertError {
|
||||||
err = fmt.Errorf("execution reverted: %v", reason)
|
err = fmt.Errorf("execution reverted: %v", reason)
|
||||||
}
|
}
|
||||||
return &revertError{
|
return &revertError{
|
||||||
error: err,
|
error: err,
|
||||||
errData: hexutil.Encode(result.Revert()),
|
reason: hexutil.Encode(result.Revert()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// revertError is an API error that encompassas an EVM revertal with JSON error
|
||||||
|
// code and a binary data blob.
|
||||||
type revertError struct {
|
type revertError struct {
|
||||||
error
|
error
|
||||||
errData interface{} // additional data
|
reason string // revert reason hex encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e revertError) ErrorCode() int {
|
// Core returns the JSON error code for a revertal.
|
||||||
// revert errors are execution errors.
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
func (e *revertError) Code() int {
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e revertError) ErrorData() interface{} {
|
// Data returns the hex encoded revert reason.
|
||||||
return e.errData
|
func (e *revertError) Data() interface{} {
|
||||||
|
return e.reason
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallContract executes a contract call.
|
// CallContract executes a contract call.
|
||||||
|
|
|
@ -463,10 +463,10 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
||||||
t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
|
t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
|
||||||
}
|
}
|
||||||
if c.expectData != nil {
|
if c.expectData != nil {
|
||||||
if rerr, ok := err.(*revertError); !ok {
|
if err, ok := err.(*revertError); !ok {
|
||||||
t.Fatalf("Expect revert error, got %T", err)
|
t.Fatalf("Expect revert error, got %T", err)
|
||||||
} else if !reflect.DeepEqual(rerr.ErrorData(), c.expectData) {
|
} else if !reflect.DeepEqual(err.Data(), c.expectData) {
|
||||||
t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, rerr.ErrorData())
|
t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.Data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -413,9 +413,7 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) {
|
||||||
resp.Set("id", req.ID)
|
resp.Set("id", req.ID)
|
||||||
|
|
||||||
var result json.RawMessage
|
var result json.RawMessage
|
||||||
err = b.client.Call(&result, req.Method, req.Params...)
|
if err = b.client.Call(&result, req.Method, req.Params...); err == nil {
|
||||||
switch err := err.(type) {
|
|
||||||
case nil:
|
|
||||||
if result == nil {
|
if result == nil {
|
||||||
// Special case null because it is decoded as an empty
|
// Special case null because it is decoded as an empty
|
||||||
// raw message for some reason.
|
// raw message for some reason.
|
||||||
|
@ -433,18 +431,21 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) {
|
||||||
resp.Set("result", resultVal)
|
resp.Set("result", resultVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case rpc.Error:
|
} else {
|
||||||
if dataErr, ok := err.(rpc.DataError); ok {
|
var (
|
||||||
setError(resp, err.ErrorCode(), err.Error(), dataErr.ErrorData())
|
code int = -32603
|
||||||
} else {
|
data interface{} = nil
|
||||||
setError(resp, err.ErrorCode(), err.Error(), nil)
|
)
|
||||||
|
if err, ok := err.(rpc.ErrorWithCode); ok {
|
||||||
|
code = err.Code()
|
||||||
}
|
}
|
||||||
default:
|
if err, ok := err.(rpc.ErrorWithData); ok {
|
||||||
setError(resp, -32603, err.Error(), nil)
|
data = err.Data()
|
||||||
|
}
|
||||||
|
setError(resp, code, err.Error(), data)
|
||||||
}
|
}
|
||||||
resps = append(resps, resp)
|
resps = append(resps, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the responses either to the callback (if supplied)
|
// Return the responses either to the callback (if supplied)
|
||||||
// or directly as the return value.
|
// or directly as the return value.
|
||||||
var result goja.Value
|
var result goja.Value
|
||||||
|
|
|
@ -871,24 +871,27 @@ func newRevertError(result *core.ExecutionResult) *revertError {
|
||||||
err = fmt.Errorf("execution reverted: %v", reason)
|
err = fmt.Errorf("execution reverted: %v", reason)
|
||||||
}
|
}
|
||||||
return &revertError{
|
return &revertError{
|
||||||
error: err,
|
error: err,
|
||||||
errData: hexutil.Encode(result.Revert()),
|
reason: hexutil.Encode(result.Revert()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// revertError is an API error that encompassas an EVM revertal with JSON error
|
||||||
|
// code and a binary data blob.
|
||||||
type revertError struct {
|
type revertError struct {
|
||||||
error
|
error
|
||||||
errData interface{} // additional data
|
reason string // revert reason hex encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e revertError) ErrorCode() int {
|
// Core returns the JSON error code for a revertal.
|
||||||
// revert errors are execution errors.
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
func (e *revertError) Code() int {
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e revertError) ErrorData() interface{} {
|
// Data returns the hex encoded revert reason.
|
||||||
return e.errData
|
func (e *revertError) Data() interface{} {
|
||||||
|
return e.reason
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call executes the given transaction on the state for the given block number.
|
// Call executes the given transaction on the state for the given block number.
|
||||||
|
|
|
@ -18,20 +18,27 @@ package rpc
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ErrorWithCode = new(methodNotFoundError)
|
||||||
|
_ ErrorWithCode = new(subscriptionNotFoundError)
|
||||||
|
_ ErrorWithCode = new(parseError)
|
||||||
|
_ ErrorWithCode = new(invalidRequestError)
|
||||||
|
_ ErrorWithCode = new(invalidMessageError)
|
||||||
|
_ ErrorWithCode = new(invalidParamsError)
|
||||||
|
)
|
||||||
|
|
||||||
const defaultErrorCode = -32000
|
const defaultErrorCode = -32000
|
||||||
|
|
||||||
type methodNotFoundError struct{ method string }
|
type methodNotFoundError struct{ method string }
|
||||||
|
|
||||||
func (e *methodNotFoundError) ErrorCode() int { return -32601 }
|
func (e *methodNotFoundError) Code() int { return -32601 }
|
||||||
|
|
||||||
func (e *methodNotFoundError) Error() string {
|
func (e *methodNotFoundError) Error() string {
|
||||||
return fmt.Sprintf("the method %s does not exist/is not available", e.method)
|
return fmt.Sprintf("the method %s does not exist/is not available", e.method)
|
||||||
}
|
}
|
||||||
|
|
||||||
type subscriptionNotFoundError struct{ namespace, subscription string }
|
type subscriptionNotFoundError struct{ namespace, subscription string }
|
||||||
|
|
||||||
func (e *subscriptionNotFoundError) ErrorCode() int { return -32601 }
|
func (e *subscriptionNotFoundError) Code() int { return -32601 }
|
||||||
|
|
||||||
func (e *subscriptionNotFoundError) Error() string {
|
func (e *subscriptionNotFoundError) Error() string {
|
||||||
return fmt.Sprintf("no %q subscription in %s namespace", e.subscription, e.namespace)
|
return fmt.Sprintf("no %q subscription in %s namespace", e.subscription, e.namespace)
|
||||||
}
|
}
|
||||||
|
@ -39,27 +46,23 @@ func (e *subscriptionNotFoundError) Error() string {
|
||||||
// Invalid JSON was received by the server.
|
// Invalid JSON was received by the server.
|
||||||
type parseError struct{ message string }
|
type parseError struct{ message string }
|
||||||
|
|
||||||
func (e *parseError) ErrorCode() int { return -32700 }
|
func (e *parseError) Code() int { return -32700 }
|
||||||
|
|
||||||
func (e *parseError) Error() string { return e.message }
|
func (e *parseError) Error() string { return e.message }
|
||||||
|
|
||||||
// received message isn't a valid request
|
// received message isn't a valid request
|
||||||
type invalidRequestError struct{ message string }
|
type invalidRequestError struct{ message string }
|
||||||
|
|
||||||
func (e *invalidRequestError) ErrorCode() int { return -32600 }
|
func (e *invalidRequestError) Code() int { return -32600 }
|
||||||
|
|
||||||
func (e *invalidRequestError) Error() string { return e.message }
|
func (e *invalidRequestError) Error() string { return e.message }
|
||||||
|
|
||||||
// received message is invalid
|
// received message is invalid
|
||||||
type invalidMessageError struct{ message string }
|
type invalidMessageError struct{ message string }
|
||||||
|
|
||||||
func (e *invalidMessageError) ErrorCode() int { return -32700 }
|
func (e *invalidMessageError) Code() int { return -32700 }
|
||||||
|
|
||||||
func (e *invalidMessageError) Error() string { return e.message }
|
func (e *invalidMessageError) Error() string { return e.message }
|
||||||
|
|
||||||
// unable to decode supplied params, or an invalid number of parameters
|
// unable to decode supplied params, or an invalid number of parameters
|
||||||
type invalidParamsError struct{ message string }
|
type invalidParamsError struct{ message string }
|
||||||
|
|
||||||
func (e *invalidParamsError) ErrorCode() int { return -32602 }
|
func (e *invalidParamsError) Code() int { return -32602 }
|
||||||
|
|
||||||
func (e *invalidParamsError) Error() string { return e.message }
|
func (e *invalidParamsError) Error() string { return e.message }
|
||||||
|
|
|
@ -301,7 +301,7 @@ func (h *handler) handleCallMsg(ctx *callProc, msg *jsonrpcMessage) *jsonrpcMess
|
||||||
if resp.Error != nil {
|
if resp.Error != nil {
|
||||||
ctx = append(ctx, "err", resp.Error.Message)
|
ctx = append(ctx, "err", resp.Error.Message)
|
||||||
if resp.Error.Data != nil {
|
if resp.Error.Data != nil {
|
||||||
ctx = append(ctx, "errdata", resp.Error.Data)
|
ctx = append(ctx, "data", resp.Error.Data)
|
||||||
}
|
}
|
||||||
h.log.Warn("Served "+msg.Method, ctx...)
|
h.log.Warn("Served "+msg.Method, ctx...)
|
||||||
} else {
|
} else {
|
||||||
|
|
16
rpc/json.go
16
rpc/json.go
|
@ -111,13 +111,13 @@ func errorMessage(err error) *jsonrpcMessage {
|
||||||
Code: defaultErrorCode,
|
Code: defaultErrorCode,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
}}
|
}}
|
||||||
ec, ok := err.(Error)
|
ec, ok := err.(ErrorWithCode)
|
||||||
if ok {
|
if ok {
|
||||||
msg.Error.Code = ec.ErrorCode()
|
msg.Error.Code = ec.Code()
|
||||||
}
|
}
|
||||||
de, ok := err.(DataError)
|
de, ok := err.(ErrorWithData)
|
||||||
if ok {
|
if ok {
|
||||||
msg.Error.Data = de.ErrorData()
|
msg.Error.Data = de.Data()
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
@ -135,14 +135,6 @@ func (err *jsonError) Error() string {
|
||||||
return err.Message
|
return err.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err *jsonError) ErrorCode() int {
|
|
||||||
return err.Code
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *jsonError) ErrorData() interface{} {
|
|
||||||
return err.Data
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conn is a subset of the methods of net.Conn which are sufficient for ServerCodec.
|
// Conn is a subset of the methods of net.Conn which are sufficient for ServerCodec.
|
||||||
type Conn interface {
|
type Conn interface {
|
||||||
io.ReadWriteCloser
|
io.ReadWriteCloser
|
||||||
|
|
14
rpc/types.go
14
rpc/types.go
|
@ -35,16 +35,14 @@ type API struct {
|
||||||
Public bool // indication if the methods must be considered safe for public use
|
Public bool // indication if the methods must be considered safe for public use
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error wraps RPC errors, which contain an error code in addition to the message.
|
// ErrorWithCode defines an error code in addition to the message.
|
||||||
type Error interface {
|
type ErrorWithCode interface {
|
||||||
Error() string // returns the message
|
Code() int // returns the code
|
||||||
ErrorCode() int // returns the code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A DataError contains some data in addition to the error message.
|
// ErrorWithData defines a data item in addition to the message.
|
||||||
type DataError interface {
|
type ErrorWithData interface {
|
||||||
Error() string // returns the message
|
Data() interface{} // returns the error data
|
||||||
ErrorData() interface{} // returns the error data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerCodec implements reading, parsing and writing RPC messages for the server side of
|
// ServerCodec implements reading, parsing and writing RPC messages for the server side of
|
||||||
|
|
Loading…
Reference in New Issue