Skip to content

Commit

Permalink
🐛 More fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
William Cory authored and William Cory committed Jun 21, 2024
1 parent ebdb1cf commit 9ec3c27
Show file tree
Hide file tree
Showing 11 changed files with 951 additions and 475 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`handleRunTxError should handle unknown EvmError subclasses 1`] = `"Uknown errror"`;
exports[`handleRunTxError should handle EvmError instances 1`] = `"invalid JUMP"`;

exports[`handleRunTxError should handle unknown EvmError subclasses 1`] = `"Unknown error: Unknown error occurred"`;
64 changes: 33 additions & 31 deletions packages/actions/src/Call/handleEvmError.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
InvalidJumpError,
AuthCallNonZeroValueExtError,
AuthCallUnsetError,
AuthInvalidSError,
Expand All @@ -22,7 +23,6 @@ import {
InvalidGasLimitError,
InvalidGasPriceError,
InvalidInputLengthError,
InvalidJumpError,
InvalidJumpSubError,
InvalidKzgInputsError,
InvalidNonceError,
Expand Down Expand Up @@ -99,39 +99,41 @@ const evmErrors = [
* @throws {never} returns errors as values
*/
export const handleRunTxError = (e) => {
if (!(e instanceof Error)) {
return new InternalEvmError('Uknown errror', { cause: /** @type {any}*/ (e) })
}
if (e.message.includes("is less than the block's baseFeePerGas")) {
return new InvalidGasPriceError(e.message, { cause: e })
}
if (e.message.includes('invalid sender address, address is not an EOA (EIP-3607)')) {
return new InvalidAddressError(e.message, { cause: e })
}
if (e.message.includes('is lower than the minimum gas limit')) {
return new InvalidGasLimitError(e.message, { cause: e })
}
if (e.message.includes('tx has a higher gas limit than the block')) {
return new GasLimitExceededError(e.message, { cause: e })
}
if (e.message.includes('block has a different hardfork than the vm')) {
return new MisconfiguredClientError(e.message, { cause: /** @type {any}*/ (e) })
}
if (e.message.includes("the tx doesn't have the correct nonce.")) {
return new InvalidNonceError(e.message, { cause: e })
}
if (e.message.includes("sender doesn't have enough funds to send tx.")) {
return new InsufficientBalanceError(e.message, { cause: /** @type {any}*/ (e) })
}
if (e.message.includes("sender doesn't have enough funds to send tx. The upfront cost is")) {
return new InsufficientBalanceError(e.message, { cause: /** @type {any}*/ (e) })
if (e instanceof Error) {
if (e.message.includes("is less than the block's baseFeePerGas")) {
return new InvalidGasPriceError(e.message, { cause: e })
}
if (e.message.includes('invalid sender address, address is not an EOA (EIP-3607)')) {
return new InvalidAddressError(e.message, { cause: e })
}
if (e.message.includes('is lower than the minimum gas limit')) {
return new InvalidGasLimitError(e.message, { cause: e })
}
if (e.message.includes('tx has a higher gas limit than the block')) {
return new GasLimitExceededError(e.message, { cause: e })
}
if (e.message.includes('block has a different hardfork than the vm')) {
return new MisconfiguredClientError(e.message, { cause: /** @type {any}*/ (e) })
}
if (e.message.includes("the tx doesn't have the correct nonce.")) {
return new InvalidNonceError(e.message, { cause: e })
}
if (e.message.includes("sender doesn't have enough funds to send tx.")) {
return new InsufficientBalanceError(e.message, { cause: /** @type {any}*/ (e) })
}
if (e.message.includes("sender doesn't have enough funds to send tx. The upfront cost is")) {
return new InsufficientBalanceError(e.message, { cause: /** @type {any}*/ (e) })
}
return new InternalEvmError(e.message, { cause: /** @type {any}*/ (e) })
}
if (!(e instanceof EvmError)) {
return new InternalEvmError(e.message, { cause: /** @type {any}*/ (e) })
console.log('not a valid EvmError')
return new InternalEvmError('Unknown error', { cause: /** @type {any}*/ (e) })
}
const ErrorConstructor = evmErrors.find((error) => error.EVMErrorMessage)
const ErrorConstructor = evmErrors.find((error) => error.EVMErrorMessage === e.error)
if (!ErrorConstructor) {
return new InternalEvmError(`Unknown error: ${e.message}`, { cause: e })
console.log('no error constructor found')
return new InternalEvmError(`Unknown error: ${e.error}`, { cause: e })
}
return new ErrorConstructor(e.message, { cause: e })
return new ErrorConstructor(e.error, { cause: e })
}
107 changes: 42 additions & 65 deletions packages/actions/src/Call/handleEvmError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('handleRunTxError', () => {
const error = 'unknown error'
const result = handleRunTxError(error)
expect(result).toBeInstanceOf(InternalEvmError)
expect(result.message).toBe('Uknown errror')
expect(result.message).toBe('Unknown error')
expect(result.cause).toBe(error)
})

Expand Down Expand Up @@ -81,76 +81,53 @@ describe('handleRunTxError', () => {
expect(result.message).toMatchSnapshot()
})

it.todo('should handle specific EvmError subclasses', () => {
it('should handle specific EvmError subclasses', () => {
const errorCases = [
{
errorInstance: new AuthCallNonZeroValueExtError('AuthCallNonZeroValueExtError'),
expectedError: AuthCallNonZeroValueExtError,
},
{ errorInstance: new AuthCallUnsetError('AuthCallUnsetError'), expectedError: AuthCallUnsetError },
{ errorInstance: new AuthInvalidSError('AuthInvalidSError'), expectedError: AuthInvalidSError },
{
errorInstance: new BLS12381FpNotInFieldError('BLS12381FpNotInFieldError'),
expectedError: BLS12381FpNotInFieldError,
},
{ errorInstance: new BLS12381InputEmptyError('BLS12381InputEmptyError'), expectedError: BLS12381InputEmptyError },
{
errorInstance: new BLS12381InvalidInputLengthError('BLS12381InvalidInputLengthError'),
expectedError: BLS12381InvalidInputLengthError,
},
{
errorInstance: new BLS12381PointNotOnCurveError('BLS12381PointNotOnCurveError'),
expectedError: BLS12381PointNotOnCurveError,
},
{
errorInstance: new CodeSizeExceedsMaximumError('CodeSizeExceedsMaximumError'),
expectedError: CodeSizeExceedsMaximumError,
},
{ errorInstance: new CodeStoreOutOfGasError('CodeStoreOutOfGasError'), expectedError: CodeStoreOutOfGasError },
{ errorInstance: new CreateCollisionError('CreateCollisionError'), expectedError: CreateCollisionError },
{ errorInstance: new InvalidCommitmentError('InvalidCommitmentError'), expectedError: InvalidCommitmentError },
{ errorInstance: new EvmRevertError('EvmRevertError'), expectedError: EvmRevertError },
{
errorInstance: new InitcodeSizeViolationError('InitcodeSizeViolationError'),
expectedError: InitcodeSizeViolationError,
},
{
errorInstance: new InsufficientBalanceError('InsufficientBalanceError'),
expectedError: InsufficientBalanceError,
},
{ errorInstance: new InternalEvmError('InternalEvmError'), expectedError: InternalEvmError },
{ errorInstance: new InvalidBeginSubError('InvalidBeginSubError'), expectedError: InvalidBeginSubError },
{
errorInstance: new InvalidBytecodeResultError('InvalidBytecodeResultError'),
expectedError: InvalidBytecodeResultError,
},
{ errorInstance: new InvalidEofFormatError('InvalidEofFormatError'), expectedError: InvalidEofFormatError },
{ errorInstance: new InvalidInputLengthError('InvalidInputLengthError'), expectedError: InvalidInputLengthError },
{ errorInstance: new InvalidJumpError('InvalidJumpError'), expectedError: InvalidJumpError },
{ errorInstance: new InvalidJumpSubError('InvalidJumpSubError'), expectedError: InvalidJumpSubError },
{ errorInstance: new InvalidKzgInputsError('InvalidKzgInputsError'), expectedError: InvalidKzgInputsError },
{ errorInstance: new InvalidOpcodeError('InvalidOpcodeError'), expectedError: InvalidOpcodeError },
{ errorInstance: new InvalidProofError('InvalidProofError'), expectedError: InvalidProofError },
{ errorInstance: new InvalidReturnSubError('InvalidReturnSubError'), expectedError: InvalidReturnSubError },
{ errorInstance: new OutOfGasError('OutOfGasError'), expectedError: OutOfGasError },
{ errorInstance: new OutOfRangeError('OutOfRangeError'), expectedError: OutOfRangeError },
{ errorInstance: new RefundExhaustedError('RefundExhaustedError'), expectedError: RefundExhaustedError },
{ errorInstance: new StackOverflowError('StackOverflowError'), expectedError: StackOverflowError },
{ errorInstance: new StackUnderflowError('StackUnderflowError'), expectedError: StackUnderflowError },
{ errorInstance: new StaticStateChangeError('StaticStateChangeError'), expectedError: StaticStateChangeError },
{ errorInstance: new StopError('StopError'), expectedError: StopError },
{ errorInstance: new ValueOverflowError('ValueOverflowError'), expectedError: ValueOverflowError },
InvalidJumpError,
AuthCallNonZeroValueExtError,
AuthCallUnsetError,
AuthInvalidSError,
BLS12381FpNotInFieldError,
BLS12381InputEmptyError,
BLS12381InvalidInputLengthError,
BLS12381PointNotOnCurveError,
CodeSizeExceedsMaximumError,
CodeStoreOutOfGasError,
CreateCollisionError,
EvmRevertError,
InitcodeSizeViolationError,
InsufficientBalanceError,
InternalEvmError,
InvalidBeginSubError,
InvalidBytecodeResultError,
InvalidCommitmentError,
InvalidEofFormatError,
InvalidInputLengthError,
InvalidJumpSubError,
InvalidKzgInputsError,
InvalidOpcodeError,
InvalidProofError,
InvalidReturnSubError,
OutOfGasError,
OutOfRangeError,
RefundExhaustedError,
StackOverflowError,
StackUnderflowError,
StaticStateChangeError,
StopError,
ValueOverflowError,
]

errorCases.forEach(({ errorInstance, expectedError }) => {
const result = handleRunTxError(errorInstance)
expect(result).toBeInstanceOf(expectedError)
expect(result.message).toBe(errorInstance.message)
expect(result.cause).toBe(errorInstance)
errorCases.forEach((constructor) => {
const err = new EvmError(constructor.EVMErrorMessage)
const result = handleRunTxError(err)
expect(result.name).toBe(constructor.name)
expect(result).toBeInstanceOf(constructor)
expect(result.cause).toBe(err)
})
})

it.todo('should handle unknown EvmError subclasses', () => {
it('should handle unknown EvmError subclasses', () => {
class UnknownEvmError extends EvmError {
constructor(message: string) {
super(message as any)
Expand Down
7 changes: 3 additions & 4 deletions packages/errors/src/ethereum/BaseError.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ const getVersion = () => '1.1.0.next-73'
export class BaseError extends Error {
/**
* @param {string} shortMessage - A short, human-readable summary of the error.
* @param {BaseErrorParameters} [args={}] - Additional parameters for the error.
* @param {BaseErrorParameters} args={} - Additional parameters for the error.
* @param {string} _tag - Internal tag for the error.
* @param {number} code - Error code analogous to the code in JSON RPC error.
* @param {number} [code] - Error code analogous to the code in JSON RPC error.
*/
constructor(shortMessage, args = {}, _tag = 'BaseError', code = 0) {
constructor(shortMessage, args, _tag, code = 0) {
if (new.target === BaseError) {
throw new TypeError('Cannot construct BaseError instances directly')
}
Expand Down Expand Up @@ -75,7 +75,6 @@ export class BaseError extends Error {
}
})()
const docsPath = args.cause instanceof BaseError ? args.cause.docsPath || args.docsPath : args.docsPath

/**
* @type {string}
*/
Expand Down
17 changes: 3 additions & 14 deletions packages/errors/src/ethereum/ExecutionErrorError.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ export class ExecutionError extends BaseError {
*
* @param {string} message - Human-readable error message.
* @param {ExecutionErrorParameters} [args={}] - Additional parameters for the BaseError.
* @param {string} [tag] - Internal name/tag for the error.
*/
constructor(message, args = {}) {
constructor(message, args = {}, tag = 'ExecutionError') {
super(
message,
{
...args,
docsBaseUrl: args.docsBaseUrl ?? 'https://tevm.sh',
docsPath: args.docsPath ?? '/reference/tevm/errors/classes/executionerror/',
},
'ExecutionError',
tag,
-32000,
)

Expand All @@ -68,16 +69,4 @@ export class ExecutionError extends BaseError {
*/
this.meta = args.meta
}

/**
* @type {string}
* @override
*/
_tag = 'ExecutionError'

/**
* @type {'ExecutionError'}
* @override
*/
name = 'ExecutionError'
}
7 changes: 0 additions & 7 deletions packages/errors/src/ethereum/GasLimitExceededError.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { BaseError } from './BaseError.js'

/**
* Represents an error that occurs when the gas limit is exceeded.
* This class is abstract and should be extended by other error classes.
*
* This error is typically encountered when a transaction or set of transactions exceed the specified gas limit.
*
Expand All @@ -29,7 +28,6 @@ import { BaseError } from './BaseError.js'
* }
* }
*
* @abstract
* @param {string} message - A human-readable error message.
* @param {GasLimitExceededErrorParameters} [args={}] - Additional parameters for the BaseError.
* @property {string} _tag - Same as name, used internally.
Expand All @@ -48,9 +46,6 @@ export class GasLimitExceededError extends BaseError {
* @param {GasLimitExceededErrorParameters} [args={}] - Additional parameters for the BaseError.
*/
constructor(message, args = {}) {
if (new.target === GasLimitExceededError) {
throw new TypeError('Cannot construct GasLimitExceededError instances directly')
}
super(
message,
{
Expand All @@ -70,14 +65,12 @@ export class GasLimitExceededError extends BaseError {

/**
* @type {string}
* @abstract
* @override
*/
_tag = 'GasLimitExceeded'

/**
* @type {string}
* @abstract
* @override
*/
name = 'GasLimitExceeded'
Expand Down
14 changes: 9 additions & 5 deletions packages/errors/src/ethereum/ethereumjs/InternalEvmError.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@ export class InternalEvmError extends BaseError {
* @param {InternalEvmErrorParameters} [args={}] - Additional parameters for the BaseError.
*/
constructor(message = 'Internal error occurred.', args = {}) {
super(message, {
...args,
docsBaseUrl: args.docsBaseUrl ?? 'https://tevm.sh',
docsPath: args.docsPath ?? '/reference/tevm/errors/classes/internalerror/',
})
super(
message,
{
...args,
docsBaseUrl: args.docsBaseUrl ?? 'https://tevm.sh',
docsPath: args.docsPath ?? '/reference/tevm/errors/classes/internalerror/',
},
'InternalEvmError',
)

/**
* @type {string}
Expand Down
28 changes: 11 additions & 17 deletions packages/errors/src/ethereum/ethereumjs/InvalidJumpError.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,21 @@ export class InvalidJumpError extends ExecutionError {
*
* @param {string} [message='Invalid JUMP error occurred.'] - Human-readable error message.
* @param {InvalidJumpErrorParameters} [args={}] - Additional parameters for the BaseError.
* @param {string} [tag] - Optionally override the name/tag for the error.
*/
constructor(message = 'Invalid JUMP error occurred.', args = {}) {
super(message, {
...args,
docsBaseUrl: args.docsBaseUrl ?? 'https://tevm.sh',
docsPath: args.docsPath ?? '/reference/tevm/errors/classes/invalidjumperror/',
})

/**
* @type {string}
* @override
*/
this.message = message

constructor(message = 'Invalid JUMP error occurred.', args = {}, tag = 'InvalidJumpError') {
super(
message,
{
...args,
docsBaseUrl: args.docsBaseUrl ?? 'https://tevm.sh',
docsPath: args.docsPath ?? '/reference/tevm/errors/classes/invalidjumperror/',
},
tag,
)
/**
* @type {object|undefined}
*/
this.meta = args.meta
/**
* @type {'InvalidJumpError'}
*/
this._tag = 'InvalidJumpError'
}
}
2 changes: 1 addition & 1 deletion packages/errors/src/fork/ForkError.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class ForkError extends BaseError {
cause:
args.cause instanceof Error
? args.cause
: new BaseError(args.cause.message, undefined, 'unknown', /** @type {number}*/ (args.cause.code)),
: new BaseError(args.cause.message, {}, 'unknown', /** @type {number}*/ (args.cause.code)),
docsBaseUrl: 'https://tevm.sh',
docsPath: '/reference/tevm/errors/classes/accountlockederror/',
},
Expand Down
Loading

0 comments on commit 9ec3c27

Please sign in to comment.