rpc: internal/ethapi: added custom error types
This commit is contained in:
committed by
Péter Szilágyi
parent
ca35628cc2
commit
d77770d96e
@ -435,6 +435,8 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) {
|
|||||||
}
|
}
|
||||||
case rpc.Error:
|
case rpc.Error:
|
||||||
setError(resp, err.ErrorCode(), err.Error())
|
setError(resp, err.ErrorCode(), err.Error())
|
||||||
|
case rpc.DataError:
|
||||||
|
resp.Set("error", map[string]interface{}{"code": -32603, "message": err.Error(), "data": err.ErrorData()})
|
||||||
default:
|
default:
|
||||||
setError(resp, -32603, err.Error())
|
setError(resp, -32603, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -864,6 +864,21 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ rpc.DataError = (*revertError)(nil)
|
||||||
|
|
||||||
|
type revertError struct {
|
||||||
|
err string // The error string
|
||||||
|
errData interface{} // additional data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e revertError) Error() string {
|
||||||
|
return e.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e revertError) ErrorData() interface{} {
|
||||||
|
return e.errData
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
// Additionally, the caller can specify a batch of contract for fields overriding.
|
// Additionally, the caller can specify a batch of contract for fields overriding.
|
||||||
@ -883,12 +898,17 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
|
|||||||
if len(result.Revert()) > 0 {
|
if len(result.Revert()) > 0 {
|
||||||
reason, err := abi.UnpackRevert(result.Revert())
|
reason, err := abi.UnpackRevert(result.Revert())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, fmt.Errorf("execution reverted: %v", reason)
|
return nil, &revertError{
|
||||||
|
err: "execution reverted",
|
||||||
|
errData: reason,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.Return(), nil
|
return result.Return(), result.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ rpc.DataError = (*estimateGasError)(nil)
|
||||||
|
|
||||||
type estimateGasError struct {
|
type estimateGasError struct {
|
||||||
error string // Concrete error type if it's failed to estimate gas usage
|
error string // Concrete error type if it's failed to estimate gas usage
|
||||||
vmerr error // Additional field, it's non-nil if the given transaction is invalid
|
vmerr error // Additional field, it's non-nil if the given transaction is invalid
|
||||||
@ -906,6 +926,10 @@ func (e estimateGasError) Error() string {
|
|||||||
return errMsg
|
return errMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e estimateGasError) ErrorData() interface{} {
|
||||||
|
return e.revert
|
||||||
|
}
|
||||||
|
|
||||||
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) {
|
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) {
|
||||||
// Binary search the gas requirement, as it may be higher than the amount used
|
// Binary search the gas requirement, as it may be higher than the amount used
|
||||||
var (
|
var (
|
||||||
|
@ -115,6 +115,10 @@ func errorMessage(err error) *jsonrpcMessage {
|
|||||||
if ok {
|
if ok {
|
||||||
msg.Error.Code = ec.ErrorCode()
|
msg.Error.Code = ec.ErrorCode()
|
||||||
}
|
}
|
||||||
|
de, ok := err.(DataError)
|
||||||
|
if ok {
|
||||||
|
msg.Error.Data = de.ErrorData()
|
||||||
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,12 @@ type Error interface {
|
|||||||
ErrorCode() int // returns the code
|
ErrorCode() int // returns the code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A DataError contains some data in addition to the error message.
|
||||||
|
type DataError interface {
|
||||||
|
Error() string // returns the message
|
||||||
|
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
|
||||||
// a RPC session. Implementations must be go-routine safe since the codec can be called in
|
// a RPC session. Implementations must be go-routine safe since the codec can be called in
|
||||||
// multiple go-routines concurrently.
|
// multiple go-routines concurrently.
|
||||||
|
Reference in New Issue
Block a user