accounts, console, internal, rpc: minor error interface cleanups

pull/21083/head
Péter Szilágyi 4 years ago
parent 53508c5d46
commit 2d3ef53c53
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
  1. 19
      accounts/abi/bind/backends/simulated.go
  2. 6
      accounts/abi/bind/backends/simulated_test.go
  3. 23
      console/bridge.go
  4. 19
      internal/ethapi/api.go
  5. 27
      rpc/errors.go
  6. 2
      rpc/handler.go
  7. 16
      rpc/json.go
  8. 14
      rpc/types.go

@ -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()
}
if err, ok := err.(rpc.ErrorWithData); ok {
data = err.Data()
} }
default: setError(resp, code, err.Error(), data)
setError(resp, -32603, err.Error(), nil)
} }
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 {

@ -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

@ -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…
Cancel
Save