From f58007f62a1059f840daedbeb829b258e07c1aaf Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 9 Sep 2021 22:50:43 -0400 Subject: [PATCH 01/22] vm: InvalidBlockHeader error --- packages/vm/src/errors.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/vm/src/errors.ts diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts new file mode 100644 index 0000000000..0a1356ade0 --- /dev/null +++ b/packages/vm/src/errors.ts @@ -0,0 +1,33 @@ +export enum ErrorCode { + INVALID_BLOCK_HEADER = 'INVALID_BLOCK_HEADER', +} + +export interface GeneralError extends Error { + code: ErrorCode + error?: Error +} + +export interface InvalidBlockHeaderError extends GeneralError { + param?: + | 'uncleHash' + | 'coinbase' + | 'stateRoot' + | 'transactionsTrie' + | 'receiptTrie' + | 'bloom' + | 'difficulty' + | 'number' + | 'gasLimit' + | 'gasUsed' + | 'timestamp' + | 'extraData' + | 'mixHash' + | 'nonce' + | 'baseFeePerGas' +} + +// Converts an ErrorCode its Typed Error + +export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER + ? InvalidBlockHeaderError + : never From c0500a40fc48f404be6b32289b285081e2d3b6ab Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 15 Sep 2021 23:42:40 -0400 Subject: [PATCH 02/22] vm: add Error Logger --- packages/vm/src/errors.ts | 84 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index 0a1356ade0..9f80bccf91 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -1,10 +1,10 @@ -export enum ErrorCode { +enum ErrorCode { INVALID_BLOCK_HEADER = 'INVALID_BLOCK_HEADER', + UNKNOWN_ERROR = 'UNKNOWN_ERROR', } export interface GeneralError extends Error { - code: ErrorCode - error?: Error + code?: T } export interface InvalidBlockHeaderError extends GeneralError { @@ -25,9 +25,83 @@ export interface InvalidBlockHeaderError extends GeneralError { + [key: string]: any +} -// Converts an ErrorCode its Typed Error - +// Convert an ErrorCode into its Typed Error export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? InvalidBlockHeaderError + : T extends ErrorCode.UNKNOWN_ERROR + ? UnknownError : never + +export class Logger { + static errors = ErrorCode + + // makeError(codedError: CodedGeneralError): Error { + // let { message } = codedError + // const { code } = codedError + // const messageDetails: Array = [] + + // if (isError(codedError, ErrorCode.INVALID_BLOCK_HEADER)) { + // messageDetails.push('Invalid param' + '=' + codedError.param) + // } + + // if (isError(codedError, ErrorCode.UNKNOWN_ERROR)) { + // Object.keys(codedError) + // .filter((key) => key !== 'message' && key !== 'code') + // .forEach((key) => { + // const value = codedError[key] + // try { + // messageDetails.push(key + '=' + JSON.stringify(value)) + // } catch { + // messageDetails.push(key + '=' + JSON.stringify(codedError[key].toString())) + // } + // }) + // } + + // messageDetails.push(`code=${codedError.code}`) + + // if (messageDetails.length) { + // message += ' (' + messageDetails.join(', ') + ')' + // } + + // const error = new Error(message) as CodedGeneralError + // error.code = code + + // // TODO: Find how to add all args + + // // Object.keys(codedError) + // // .filter((key) => key !== 'message' && key !== 'code') + // // .forEach((key) => { + // // error[key] = codedError[key] + // // }) + + // return error + // } + + throwError(error: CodedGeneralError): never { + if (!error.code) { + error.code = ErrorCode.UNKNOWN_ERROR + } + + throw error + } +} + +export const log = new Logger() + +export function isError>( + error: Error, + code: K +): error is T { + if (error && (error).code === code) { + return true + } + return false +} + +export function isInvalidBlockHeader(error: Error): error is InvalidBlockHeaderError { + return isError(error, ErrorCode.INVALID_BLOCK_HEADER) +} From 40c8df06f4bcde95d302c4dc61eca3a8d972b75f Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 15 Sep 2021 23:43:15 -0400 Subject: [PATCH 03/22] vm: remove makeError method --- packages/vm/src/errors.ts | 42 --------------------------------------- 1 file changed, 42 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index 9f80bccf91..164bed4b1d 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -39,48 +39,6 @@ export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER export class Logger { static errors = ErrorCode - // makeError(codedError: CodedGeneralError): Error { - // let { message } = codedError - // const { code } = codedError - // const messageDetails: Array = [] - - // if (isError(codedError, ErrorCode.INVALID_BLOCK_HEADER)) { - // messageDetails.push('Invalid param' + '=' + codedError.param) - // } - - // if (isError(codedError, ErrorCode.UNKNOWN_ERROR)) { - // Object.keys(codedError) - // .filter((key) => key !== 'message' && key !== 'code') - // .forEach((key) => { - // const value = codedError[key] - // try { - // messageDetails.push(key + '=' + JSON.stringify(value)) - // } catch { - // messageDetails.push(key + '=' + JSON.stringify(codedError[key].toString())) - // } - // }) - // } - - // messageDetails.push(`code=${codedError.code}`) - - // if (messageDetails.length) { - // message += ' (' + messageDetails.join(', ') + ')' - // } - - // const error = new Error(message) as CodedGeneralError - // error.code = code - - // // TODO: Find how to add all args - - // // Object.keys(codedError) - // // .filter((key) => key !== 'message' && key !== 'code') - // // .forEach((key) => { - // // error[key] = codedError[key] - // // }) - - // return error - // } - throwError(error: CodedGeneralError): never { if (!error.code) { error.code = ErrorCode.UNKNOWN_ERROR From 17831d2632e589a20e743ca2e784ebbcc302fc82 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 28 Sep 2021 20:05:27 -0400 Subject: [PATCH 04/22] vm: add makeError method to ErrorLogger --- packages/vm/src/errors.ts | 48 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index 164bed4b1d..f0d7f3dada 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -36,19 +36,61 @@ export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? UnknownError : never -export class Logger { +export class ErrorLogger { static errors = ErrorCode + makeError(codedError: CodedGeneralError): Error { + let { message } = codedError + const { code } = codedError + const messageDetails: Array = [] + + if (isError(codedError, ErrorCode.INVALID_BLOCK_HEADER)) { + messageDetails.push('Invalid param' + '=' + codedError.param) + } + + if (isError(codedError, ErrorCode.UNKNOWN_ERROR)) { + Object.keys(codedError) + .filter((key) => key !== 'message' && key !== 'code') + .forEach((key) => { + const value = codedError[key] + try { + messageDetails.push(key + '=' + JSON.stringify(value)) + } catch { + messageDetails.push(key + '=' + JSON.stringify(codedError[key].toString())) + } + }) + } + + messageDetails.push(`code=${codedError.code}`) + + if (messageDetails.length) { + message += ' (' + messageDetails.join(', ') + ')' + } + + const error = new Error(message) as CodedGeneralError + error.code = code + error['name'] = 'hi' + + Object.keys(codedError) + .filter((key) => key !== 'message' && key !== 'code') + .forEach((key) => { + const typedKey = key as keyof typeof codedError + error[typedKey] = codedError[typedKey] + }) + + throw error + } + throwError(error: CodedGeneralError): never { if (!error.code) { error.code = ErrorCode.UNKNOWN_ERROR } - throw error + throw this.makeError(error) } } -export const log = new Logger() +export const errorLog = new ErrorLogger() export function isError>( error: Error, From db7cf8843f52ac01a153c63dc95865a34cdd3575 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 28 Sep 2021 20:06:01 -0400 Subject: [PATCH 05/22] vm: cleanup error logger makeError method --- packages/vm/src/errors.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index f0d7f3dada..f6e0a9de92 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -68,8 +68,6 @@ export class ErrorLogger { } const error = new Error(message) as CodedGeneralError - error.code = code - error['name'] = 'hi' Object.keys(codedError) .filter((key) => key !== 'message' && key !== 'code') From 4b6e9e42e610c81804895785eb027e645775db81 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 28 Sep 2021 22:55:39 -0400 Subject: [PATCH 06/22] vm: clean up error exports and test throwError method --- packages/vm/src/errors.ts | 23 ++++++++++++++--------- packages/vm/src/runBlock.ts | 8 +++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index f6e0a9de92..b1f1c471a2 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -1,13 +1,13 @@ -enum ErrorCode { +export enum ErrorCode { INVALID_BLOCK_HEADER = 'INVALID_BLOCK_HEADER', UNKNOWN_ERROR = 'UNKNOWN_ERROR', } -export interface GeneralError extends Error { +interface GeneralError extends Error { code?: T } -export interface InvalidBlockHeaderError extends GeneralError { +interface InvalidBlockHeaderError extends GeneralError { param?: | 'uncleHash' | 'coinbase' @@ -25,18 +25,18 @@ export interface InvalidBlockHeaderError extends GeneralError { +interface UnknownError extends GeneralError { [key: string]: any } // Convert an ErrorCode into its Typed Error -export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER +type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? InvalidBlockHeaderError : T extends ErrorCode.UNKNOWN_ERROR ? UnknownError : never -export class ErrorLogger { +class ErrorLogger { static errors = ErrorCode makeError(codedError: CodedGeneralError): Error { @@ -44,11 +44,11 @@ export class ErrorLogger { const { code } = codedError const messageDetails: Array = [] - if (isError(codedError, ErrorCode.INVALID_BLOCK_HEADER)) { + if (isInvalidBlockHeaderError(codedError)) { messageDetails.push('Invalid param' + '=' + codedError.param) } - if (isError(codedError, ErrorCode.UNKNOWN_ERROR)) { + if (isUnknownError(codedError)) { Object.keys(codedError) .filter((key) => key !== 'message' && key !== 'code') .forEach((key) => { @@ -79,6 +79,7 @@ export class ErrorLogger { throw error } + // TODO: Make name (and maybe message?) optional fields when throwing an error throwError(error: CodedGeneralError): never { if (!error.code) { error.code = ErrorCode.UNKNOWN_ERROR @@ -100,6 +101,10 @@ export function isError>( return false } -export function isInvalidBlockHeader(error: Error): error is InvalidBlockHeaderError { +export function isInvalidBlockHeaderError(error: Error): error is InvalidBlockHeaderError { return isError(error, ErrorCode.INVALID_BLOCK_HEADER) } + +export function isUnknownError(error: Error): error is UnknownError { + return isError(error, ErrorCode.UNKNOWN_ERROR) +} diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 62d8d05962..4a15302095 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -18,6 +18,7 @@ import * as DAOConfig from './config/dao_fork_accounts_config.json' // deprecated and may be removed soon, please // update your imports to the new types file. import { PreByzantiumTxReceipt, PostByzantiumTxReceipt, EIP2930Receipt } from './types' +import { ErrorCode, errorLog } from './errors' export { PreByzantiumTxReceipt, PostByzantiumTxReceipt, EIP2930Receipt } const debug = createDebugLogger('vm:block') @@ -230,7 +231,12 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise Date: Tue, 28 Sep 2021 23:18:46 -0400 Subject: [PATCH 07/22] vm: simplify usage of throwError method --- packages/vm/src/errors.ts | 27 +++++++++++++++------------ packages/vm/src/runBlock.ts | 5 +---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index b1f1c471a2..aac2c3c3b8 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -3,7 +3,7 @@ export enum ErrorCode { UNKNOWN_ERROR = 'UNKNOWN_ERROR', } -interface GeneralError extends Error { +interface GeneralError extends Partial { code?: T } @@ -79,20 +79,23 @@ class ErrorLogger { throw error } - // TODO: Make name (and maybe message?) optional fields when throwing an error - throwError(error: CodedGeneralError): never { - if (!error.code) { - error.code = ErrorCode.UNKNOWN_ERROR - } - - throw this.makeError(error) + throwError( + message?: string, + code?: ErrorCode, + params?: Omit, 'message' | 'code'> + ): never { + throw this.makeError({ + message: message ?? 'Unknown error', + code: code ?? ErrorCode.UNKNOWN_ERROR, + ...params, + } as CodedGeneralError) } } export const errorLog = new ErrorLogger() -export function isError>( - error: Error, +function isError>( + error: GeneralError, code: K ): error is T { if (error && (error).code === code) { @@ -101,10 +104,10 @@ export function isError>( return false } -export function isInvalidBlockHeaderError(error: Error): error is InvalidBlockHeaderError { +function isInvalidBlockHeaderError(error: GeneralError): error is InvalidBlockHeaderError { return isError(error, ErrorCode.INVALID_BLOCK_HEADER) } -export function isUnknownError(error: Error): error is UnknownError { +function isUnknownError(error: GeneralError): error is UnknownError { return isError(error, ErrorCode.UNKNOWN_ERROR) } diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 4a15302095..ac23a20ed8 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -231,11 +231,8 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise Date: Tue, 28 Sep 2021 23:22:33 -0400 Subject: [PATCH 08/22] vm: fix linting errors --- packages/vm/src/errors.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index aac2c3c3b8..4f19bc8d49 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -41,11 +41,10 @@ class ErrorLogger { makeError(codedError: CodedGeneralError): Error { let { message } = codedError - const { code } = codedError const messageDetails: Array = [] if (isInvalidBlockHeaderError(codedError)) { - messageDetails.push('Invalid param' + '=' + codedError.param) + messageDetails.push(`Invalid param = ${codedError.param}`) } if (isUnknownError(codedError)) { From 3c8b8e1e77e2ccc71d9ea78d712876dedf283a73 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 28 Sep 2021 23:26:39 -0400 Subject: [PATCH 09/22] vm: implement additional block header errors --- packages/vm/src/runBlock.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index ac23a20ed8..fcc00eebdb 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -205,7 +205,9 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise Date: Tue, 28 Sep 2021 23:43:07 -0400 Subject: [PATCH 10/22] vm: simplify throwError method further and fix missing ErrorCode --- packages/vm/src/errors.ts | 7 +++---- packages/vm/src/runBlock.ts | 19 ++++++++----------- packages/vm/tests/api/runBlock.spec.ts | 5 ++++- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index 4f19bc8d49..e0b28208c2 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -30,7 +30,7 @@ interface UnknownError extends GeneralError { } // Convert an ErrorCode into its Typed Error -type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER +export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? InvalidBlockHeaderError : T extends ErrorCode.UNKNOWN_ERROR ? UnknownError @@ -67,6 +67,7 @@ class ErrorLogger { } const error = new Error(message) as CodedGeneralError + error.code = codedError.code Object.keys(codedError) .filter((key) => key !== 'message' && key !== 'code') @@ -79,12 +80,10 @@ class ErrorLogger { } throwError( - message?: string, code?: ErrorCode, - params?: Omit, 'message' | 'code'> + params?: Omit, 'code'> ): never { throw this.makeError({ - message: message ?? 'Unknown error', code: code ?? ErrorCode.UNKNOWN_ERROR, ...params, } as CodedGeneralError) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index fcc00eebdb..e360e9003f 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -205,7 +205,7 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise API parameter usage/data errors', async (t) => { await vm .runBlock({ block }) .then(() => t.fail('should have returned error')) - .catch((e) => t.ok(e.message.includes('Invalid block'))) + .catch((e) => + t.ok(e.code === ErrorCode.INVALID_BLOCK_HEADER /* && e.param === 'gasLimit' */) + ) }) t.test('should fail when block validation fails', async (t) => { From 3939a9254c8309d42886d852dfdf48abbc43ff38 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 28 Sep 2021 23:44:15 -0400 Subject: [PATCH 11/22] vm: reimplement commented out code --- packages/vm/tests/api/runBlock.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/vm/tests/api/runBlock.spec.ts b/packages/vm/tests/api/runBlock.spec.ts index 47ce8f4a1a..4434a4bf49 100644 --- a/packages/vm/tests/api/runBlock.spec.ts +++ b/packages/vm/tests/api/runBlock.spec.ts @@ -213,9 +213,7 @@ tape('runBlock() -> API parameter usage/data errors', async (t) => { await vm .runBlock({ block }) .then(() => t.fail('should have returned error')) - .catch((e) => - t.ok(e.code === ErrorCode.INVALID_BLOCK_HEADER /* && e.param === 'gasLimit' */) - ) + .catch((e) => t.ok(e.code === ErrorCode.INVALID_BLOCK_HEADER && e.param === 'gasLimit')) }) t.test('should fail when block validation fails', async (t) => { From f6f488dd4fd70e7d845bed9e9122fb70ad3d8d5d Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 29 Sep 2021 23:00:22 -0400 Subject: [PATCH 12/22] vm: fix throwError type for dynamic inference in usage --- packages/vm/src/errors.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index e0b28208c2..d7a182224e 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -36,7 +36,7 @@ export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? UnknownError : never -class ErrorLogger { +export class ErrorLogger { static errors = ErrorCode makeError(codedError: CodedGeneralError): Error { @@ -79,10 +79,7 @@ class ErrorLogger { throw error } - throwError( - code?: ErrorCode, - params?: Omit, 'code'> - ): never { + throwError(code?: T, params?: Omit, 'code'>): never { throw this.makeError({ code: code ?? ErrorCode.UNKNOWN_ERROR, ...params, From 3f7a645c2bdae5ec6cedcfa6e80f71432dc8c690 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 29 Sep 2021 23:14:47 -0400 Subject: [PATCH 13/22] vm: add errorlogger tests --- packages/vm/src/errors.ts | 5 +- packages/vm/tests/api/errors.spec.ts | 119 +++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 packages/vm/tests/api/errors.spec.ts diff --git a/packages/vm/src/errors.ts b/packages/vm/src/errors.ts index d7a182224e..f23749d0ae 100644 --- a/packages/vm/src/errors.ts +++ b/packages/vm/src/errors.ts @@ -44,7 +44,7 @@ export class ErrorLogger { const messageDetails: Array = [] if (isInvalidBlockHeaderError(codedError)) { - messageDetails.push(`Invalid param = ${codedError.param}`) + messageDetails.push(`Invalid param=${codedError.param}`) } if (isUnknownError(codedError)) { @@ -63,7 +63,7 @@ export class ErrorLogger { messageDetails.push(`code=${codedError.code}`) if (messageDetails.length) { - message += ' (' + messageDetails.join(', ') + ')' + message += ' | Details: ' + messageDetails.join(', ') } const error = new Error(message) as CodedGeneralError @@ -82,6 +82,7 @@ export class ErrorLogger { throwError(code?: T, params?: Omit, 'code'>): never { throw this.makeError({ code: code ?? ErrorCode.UNKNOWN_ERROR, + message: params?.message ?? '', ...params, } as CodedGeneralError) } diff --git a/packages/vm/tests/api/errors.spec.ts b/packages/vm/tests/api/errors.spec.ts new file mode 100644 index 0000000000..bc19554b8d --- /dev/null +++ b/packages/vm/tests/api/errors.spec.ts @@ -0,0 +1,119 @@ +import tape from 'tape' +import { ErrorCode, ErrorLogger } from '../../src/errors' + +tape('ErrorLogger', (t) => { + const errorLog = new ErrorLogger() + + t.test('should assign the UNKNOWN_ERROR code to errors with undefined code', (st) => { + let error: any + + try { + errorLog.throwError() + } catch (e) { + error = e + } + + st.equal(error.code, ErrorCode.UNKNOWN_ERROR) + st.end() + }), + t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorInfo1: 'Information on the error', + errorInfo2: 'More information on the error', + }) + } catch (e) { + error = e + } + + st.equal(error.errorInfo1, 'Information on the error') + st.equal(error.errorInfo2, 'More information on the error') + st.end() + }) + t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorInfo1: 'Information on the error', + errorInfo2: 'More information on the error', + }) + } catch (e) { + error = e + } + + st.equal(error.code, ErrorCode.UNKNOWN_ERROR) + st.end() + }), + t.test('should add all error params to error message details', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorInfo1: 'Information on the error', + errorInfo2: 'More information on the error', + }) + } catch (e) { + error = e + } + + st.equal( + error.message, + ' | Details: errorInfo1="Information on the error", errorInfo2="More information on the error", code=UNKNOWN_ERROR' + ) + st.end() + }), + t.test('should append all error params to existing error message', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + message: 'Error Message', + errorInfo1: 'Information on the error', + errorInfo2: 'More information on the error', + }) + } catch (e) { + error = e + } + + st.equal( + error.message, + 'Error Message | Details: errorInfo1="Information on the error", errorInfo2="More information on the error", code=UNKNOWN_ERROR' + ) + st.end() + }) + t.test('should populate an error with INVALID_BLOCK_HEADER with the "param" prop', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.INVALID_BLOCK_HEADER, { + param: 'difficulty', + }) + } catch (e) { + error = e + } + + st.equal(error.param, 'difficulty') + st.end() + }), + t.test('should add the "param" prop to the INVALID_BLOCK_HEADER error message', (st) => { + let error: any + + try { + errorLog.throwError(ErrorCode.INVALID_BLOCK_HEADER, { + message: 'Gas limit higher than maximum', + param: 'gasLimit', + }) + } catch (e) { + error = e + } + + st.equal( + error.message, + 'Gas limit higher than maximum | Details: Invalid param=gasLimit, code=INVALID_BLOCK_HEADER' + ) + st.end() + }) +}) From 6285dd5710f478f686c99926d82039ccbcd84c35 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 8 Feb 2022 22:12:58 -0500 Subject: [PATCH 14/22] util: move errors.ts from vm to util package --- packages/{vm => util}/src/errors.ts | 43 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) rename packages/{vm => util}/src/errors.ts (94%) diff --git a/packages/vm/src/errors.ts b/packages/util/src/errors.ts similarity index 94% rename from packages/vm/src/errors.ts rename to packages/util/src/errors.ts index f23749d0ae..14368d5860 100644 --- a/packages/vm/src/errors.ts +++ b/packages/util/src/errors.ts @@ -25,6 +25,7 @@ interface InvalidBlockHeaderError extends GeneralError { [key: string]: any } @@ -36,6 +37,24 @@ export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER ? UnknownError : never +function isError>( + error: GeneralError, + code: K +): error is T { + if (error && (error).code === code) { + return true + } + return false +} + +function isInvalidBlockHeaderError(error: GeneralError): error is InvalidBlockHeaderError { + return isError(error, ErrorCode.INVALID_BLOCK_HEADER) +} + +function isUnknownError(error: GeneralError): error is UnknownError { + return isError(error, ErrorCode.UNKNOWN_ERROR) +} + export class ErrorLogger { static errors = ErrorCode @@ -43,13 +62,13 @@ export class ErrorLogger { let { message } = codedError const messageDetails: Array = [] - if (isInvalidBlockHeaderError(codedError)) { + if (isInvalidBlockHeaderError(codedError) && codedError.param) { messageDetails.push(`Invalid param=${codedError.param}`) } if (isUnknownError(codedError)) { Object.keys(codedError) - .filter((key) => key !== 'message' && key !== 'code') + .filter((key) => ['message', 'code', 'stack'].includes(key)) .forEach((key) => { const value = codedError[key] try { @@ -82,28 +101,10 @@ export class ErrorLogger { throwError(code?: T, params?: Omit, 'code'>): never { throw this.makeError({ code: code ?? ErrorCode.UNKNOWN_ERROR, - message: params?.message ?? '', + message: params?.message, ...params, } as CodedGeneralError) } } export const errorLog = new ErrorLogger() - -function isError>( - error: GeneralError, - code: K -): error is T { - if (error && (error).code === code) { - return true - } - return false -} - -function isInvalidBlockHeaderError(error: GeneralError): error is InvalidBlockHeaderError { - return isError(error, ErrorCode.INVALID_BLOCK_HEADER) -} - -function isUnknownError(error: GeneralError): error is UnknownError { - return isError(error, ErrorCode.UNKNOWN_ERROR) -} From 1c14b7d715b82c89a588de313e298698d00a6373 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Tue, 8 Feb 2022 23:06:15 -0500 Subject: [PATCH 15/22] vm: import error from util --- packages/util/src/index.ts | 5 +++++ packages/vm/src/runBlock.ts | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/util/src/index.ts b/packages/util/src/index.ts index bda39a3f6c..d079db4297 100644 --- a/packages/util/src/index.ts +++ b/packages/util/src/index.ts @@ -13,6 +13,11 @@ export * from './account' */ export * from './address' +/** + * Errors + */ +export * from './errors' + /** * Hash functions */ diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 08e99f8ec1..d521eed1d0 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -1,6 +1,6 @@ import { debug as createDebugLogger } from 'debug' import { BaseTrie as Trie } from 'merkle-patricia-tree' -import { Account, Address, BN, intToBuffer, rlp } from 'ethereumjs-util' +import { Account, Address, BN, errorLog, ErrorCode, intToBuffer, rlp } from 'ethereumjs-util' import { Block } from '@ethereumjs/block' import { ConsensusType } from '@ethereumjs/common' import VM from './index' @@ -17,7 +17,6 @@ import * as DAOConfig from './config/dao_fork_accounts_config.json' // deprecated and may be removed soon, please // update your imports to the new types file. import { PreByzantiumTxReceipt, PostByzantiumTxReceipt, EIP2930Receipt } from './types' -import { ErrorCode, errorLog } from './errors' export { PreByzantiumTxReceipt, PostByzantiumTxReceipt, EIP2930Receipt } const debug = createDebugLogger('vm:block') From 1b27ec76af7f53bdbebfc21c0f4eb9c684f376a8 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 9 Feb 2022 23:11:58 -0500 Subject: [PATCH 16/22] util: more general Invalid Param ErrorCode --- packages/util/src/errors.ts | 30 +++++++------------------- packages/vm/src/runBlock.ts | 15 ++++++++----- packages/vm/tests/api/runBlock.spec.ts | 5 ++--- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts index 14368d5860..36f6869d87 100644 --- a/packages/util/src/errors.ts +++ b/packages/util/src/errors.ts @@ -1,5 +1,6 @@ export enum ErrorCode { INVALID_BLOCK_HEADER = 'INVALID_BLOCK_HEADER', + INVALID_PARAM = 'INVALID_PARAM', UNKNOWN_ERROR = 'UNKNOWN_ERROR', } @@ -7,23 +8,8 @@ interface GeneralError extends Partial { code?: T } -interface InvalidBlockHeaderError extends GeneralError { - param?: - | 'uncleHash' - | 'coinbase' - | 'stateRoot' - | 'transactionsTrie' - | 'receiptTrie' - | 'bloom' - | 'difficulty' - | 'number' - | 'gasLimit' - | 'gasUsed' - | 'timestamp' - | 'extraData' - | 'mixHash' - | 'nonce' - | 'baseFeePerGas' +interface InvalidParamError extends GeneralError { + param?: string } interface UnknownError extends GeneralError { @@ -31,8 +17,8 @@ interface UnknownError extends GeneralError { } // Convert an ErrorCode into its Typed Error -export type CodedGeneralError = T extends ErrorCode.INVALID_BLOCK_HEADER - ? InvalidBlockHeaderError +export type CodedGeneralError = T extends ErrorCode.INVALID_PARAM + ? InvalidParamError : T extends ErrorCode.UNKNOWN_ERROR ? UnknownError : never @@ -47,8 +33,8 @@ function isError>( return false } -function isInvalidBlockHeaderError(error: GeneralError): error is InvalidBlockHeaderError { - return isError(error, ErrorCode.INVALID_BLOCK_HEADER) +function isInvalidParamError(error: GeneralError): error is InvalidParamError { + return isError(error, ErrorCode.INVALID_PARAM) } function isUnknownError(error: GeneralError): error is UnknownError { @@ -62,7 +48,7 @@ export class ErrorLogger { let { message } = codedError const messageDetails: Array = [] - if (isInvalidBlockHeaderError(codedError) && codedError.param) { + if (isInvalidParamError(codedError) && typeof codedError.param !== 'undefined') { messageDetails.push(`Invalid param=${codedError.param}`) } diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index d521eed1d0..fe9956ebd5 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -202,8 +202,9 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise API parameter usage/data errors', async (t) => { await vm .runBlock({ block }) .then(() => t.fail('should have returned error')) - .catch((e) => t.ok(e.code === ErrorCode.INVALID_BLOCK_HEADER && e.param === 'gasLimit')) + .catch((e) => t.ok(e.code === ErrorCode.INVALID_PARAM && e.param === 'gasLimit')) }) t.test('should fail when block validation fails', async (t) => { From cf127bb09935f41e68c1e37725effbfe2533cfc5 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 9 Feb 2022 23:39:06 -0500 Subject: [PATCH 17/22] util: cleanup makeError --- packages/util/src/errors.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts index 36f6869d87..0b724e5913 100644 --- a/packages/util/src/errors.ts +++ b/packages/util/src/errors.ts @@ -87,7 +87,6 @@ export class ErrorLogger { throwError(code?: T, params?: Omit, 'code'>): never { throw this.makeError({ code: code ?? ErrorCode.UNKNOWN_ERROR, - message: params?.message, ...params, } as CodedGeneralError) } From b1767f058c7919f6f1a1b78c0159f0d29edcd080 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 9 Feb 2022 23:44:17 -0500 Subject: [PATCH 18/22] util: move error test from vm to util --- packages/{vm/tests/api => util/test}/errors.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename packages/{vm/tests/api => util/test}/errors.spec.ts (87%) diff --git a/packages/vm/tests/api/errors.spec.ts b/packages/util/test/errors.spec.ts similarity index 87% rename from packages/vm/tests/api/errors.spec.ts rename to packages/util/test/errors.spec.ts index bc19554b8d..c9f7fa00f1 100644 --- a/packages/vm/tests/api/errors.spec.ts +++ b/packages/util/test/errors.spec.ts @@ -1,5 +1,5 @@ import tape from 'tape' -import { ErrorCode, ErrorLogger } from '../../src/errors' +import { ErrorCode, ErrorLogger } from '../src/errors' tape('ErrorLogger', (t) => { const errorLog = new ErrorLogger() @@ -84,11 +84,11 @@ tape('ErrorLogger', (t) => { ) st.end() }) - t.test('should populate an error with INVALID_BLOCK_HEADER with the "param" prop', (st) => { + t.test('should populate an error with INVALID_PARAM with the "param" prop', (st) => { let error: any try { - errorLog.throwError(ErrorCode.INVALID_BLOCK_HEADER, { + errorLog.throwError(ErrorCode.INVALID_PARAM, { param: 'difficulty', }) } catch (e) { @@ -98,11 +98,11 @@ tape('ErrorLogger', (t) => { st.equal(error.param, 'difficulty') st.end() }), - t.test('should add the "param" prop to the INVALID_BLOCK_HEADER error message', (st) => { + t.test('should add the "param" prop to the INVALID_PARAM error message', (st) => { let error: any try { - errorLog.throwError(ErrorCode.INVALID_BLOCK_HEADER, { + errorLog.throwError(ErrorCode.INVALID_PARAM, { message: 'Gas limit higher than maximum', param: 'gasLimit', }) @@ -112,7 +112,7 @@ tape('ErrorLogger', (t) => { st.equal( error.message, - 'Gas limit higher than maximum | Details: Invalid param=gasLimit, code=INVALID_BLOCK_HEADER' + 'Gas limit higher than maximum | Details: Invalid param=gasLimit, code=INVALID_PARAM' ) st.end() }) From 052687c4a6827b42de13d0f77ead75f403bda0a5 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 9 Feb 2022 23:51:07 -0500 Subject: [PATCH 19/22] chore: remove unnecessary enum member --- packages/util/src/errors.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts index 0b724e5913..b8b3e2d829 100644 --- a/packages/util/src/errors.ts +++ b/packages/util/src/errors.ts @@ -1,5 +1,4 @@ export enum ErrorCode { - INVALID_BLOCK_HEADER = 'INVALID_BLOCK_HEADER', INVALID_PARAM = 'INVALID_PARAM', UNKNOWN_ERROR = 'UNKNOWN_ERROR', } From fd78bb9f75a36391576a32f9c474db1b3d768f3e Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 20 Feb 2022 22:56:11 -0500 Subject: [PATCH 20/22] feat: consistent stack trace and only export ErrorLogger --- packages/util/src/errors.ts | 53 ++++++++++++++------------ packages/util/test/errors.spec.ts | 18 ++++----- packages/vm/src/runBlock.ts | 12 +++--- packages/vm/tests/api/runBlock.spec.ts | 4 +- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts index b8b3e2d829..92ebd1a051 100644 --- a/packages/util/src/errors.ts +++ b/packages/util/src/errors.ts @@ -1,4 +1,4 @@ -export enum ErrorCode { +enum ErrorCode { INVALID_PARAM = 'INVALID_PARAM', UNKNOWN_ERROR = 'UNKNOWN_ERROR', } @@ -16,7 +16,7 @@ interface UnknownError extends GeneralError { } // Convert an ErrorCode into its Typed Error -export type CodedGeneralError = T extends ErrorCode.INVALID_PARAM +type CodedGeneralError = T extends ErrorCode.INVALID_PARAM ? InvalidParamError : T extends ErrorCode.UNKNOWN_ERROR ? UnknownError @@ -44,47 +44,50 @@ export class ErrorLogger { static errors = ErrorCode makeError(codedError: CodedGeneralError): Error { - let { message } = codedError + const { code, message, ...params } = codedError const messageDetails: Array = [] - if (isInvalidParamError(codedError) && typeof codedError.param !== 'undefined') { + if (isInvalidParamError(codedError) && typeof params.param !== 'undefined') { messageDetails.push(`Invalid param=${codedError.param}`) } if (isUnknownError(codedError)) { - Object.keys(codedError) - .filter((key) => ['message', 'code', 'stack'].includes(key)) - .forEach((key) => { - const value = codedError[key] - try { - messageDetails.push(key + '=' + JSON.stringify(value)) - } catch { - messageDetails.push(key + '=' + JSON.stringify(codedError[key].toString())) - } - }) + Object.keys(params).forEach((key) => { + const value = codedError[key] + try { + messageDetails.push(key + '=' + JSON.stringify(value)) + } catch { + messageDetails.push(key + '=' + JSON.stringify(codedError[key].toString())) + } + }) } - messageDetails.push(`code=${codedError.code}`) + messageDetails.push(`code=${code}`) + + let errorMessage = message ?? '' if (messageDetails.length) { - message += ' | Details: ' + messageDetails.join(', ') + errorMessage += ' | Details: ' + messageDetails.join(', ') } - const error = new Error(message) as CodedGeneralError + const error = new Error(errorMessage) as CodedGeneralError error.code = codedError.code - Object.keys(codedError) - .filter((key) => key !== 'message' && key !== 'code') - .forEach((key) => { - const typedKey = key as keyof typeof codedError - error[typedKey] = codedError[typedKey] - }) + Object.keys(params).forEach((key) => { + const typedKey = key as keyof typeof codedError + error[typedKey] = codedError[typedKey] + }) + + Error.captureStackTrace(error, this.throwError) throw error } - throwError(code?: T, params?: Omit, 'code'>): never { - throw this.makeError({ + throwError( + code?: T, + params?: Omit, 'code' | 'stack'> + ): void { + this.makeError({ code: code ?? ErrorCode.UNKNOWN_ERROR, ...params, } as CodedGeneralError) diff --git a/packages/util/test/errors.spec.ts b/packages/util/test/errors.spec.ts index c9f7fa00f1..4cc3d7a6aa 100644 --- a/packages/util/test/errors.spec.ts +++ b/packages/util/test/errors.spec.ts @@ -1,5 +1,5 @@ import tape from 'tape' -import { ErrorCode, ErrorLogger } from '../src/errors' +import { ErrorLogger } from '../src/errors' tape('ErrorLogger', (t) => { const errorLog = new ErrorLogger() @@ -13,14 +13,14 @@ tape('ErrorLogger', (t) => { error = e } - st.equal(error.code, ErrorCode.UNKNOWN_ERROR) + st.equal(error.code, ErrorLogger.errors.UNKNOWN_ERROR) st.end() }), t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { let error: any try { - errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { errorInfo1: 'Information on the error', errorInfo2: 'More information on the error', }) @@ -36,7 +36,7 @@ tape('ErrorLogger', (t) => { let error: any try { - errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { errorInfo1: 'Information on the error', errorInfo2: 'More information on the error', }) @@ -44,14 +44,14 @@ tape('ErrorLogger', (t) => { error = e } - st.equal(error.code, ErrorCode.UNKNOWN_ERROR) + st.equal(error.code, ErrorLogger.errors.UNKNOWN_ERROR) st.end() }), t.test('should add all error params to error message details', (st) => { let error: any try { - errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { errorInfo1: 'Information on the error', errorInfo2: 'More information on the error', }) @@ -69,7 +69,7 @@ tape('ErrorLogger', (t) => { let error: any try { - errorLog.throwError(ErrorCode.UNKNOWN_ERROR, { + errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { message: 'Error Message', errorInfo1: 'Information on the error', errorInfo2: 'More information on the error', @@ -88,7 +88,7 @@ tape('ErrorLogger', (t) => { let error: any try { - errorLog.throwError(ErrorCode.INVALID_PARAM, { + errorLog.throwError(ErrorLogger.errors.INVALID_PARAM, { param: 'difficulty', }) } catch (e) { @@ -102,7 +102,7 @@ tape('ErrorLogger', (t) => { let error: any try { - errorLog.throwError(ErrorCode.INVALID_PARAM, { + errorLog.throwError(ErrorLogger.errors.INVALID_PARAM, { message: 'Gas limit higher than maximum', param: 'gasLimit', }) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index fe9956ebd5..3ad7021344 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -1,6 +1,6 @@ import { debug as createDebugLogger } from 'debug' import { BaseTrie as Trie } from 'merkle-patricia-tree' -import { Account, Address, BN, errorLog, ErrorCode, intToBuffer, rlp } from 'ethereumjs-util' +import { Account, Address, BN, errorLog, ErrorLogger, intToBuffer, rlp } from 'ethereumjs-util' import { Block } from '@ethereumjs/block' import { ConsensusType } from '@ethereumjs/common' import VM from './index' @@ -202,7 +202,7 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise API parameter usage/data errors', async (t) => { await vm .runBlock({ block }) .then(() => t.fail('should have returned error')) - .catch((e) => t.ok(e.code === ErrorCode.INVALID_PARAM && e.param === 'gasLimit')) + .catch((e) => t.ok(e.code === ErrorLogger.errors.INVALID_PARAM && e.param === 'gasLimit')) }) t.test('should fail when block validation fails', async (t) => { From e359bffb2c3662847ad41fc4a6a813253af00f32 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 20 Feb 2022 23:18:01 -0500 Subject: [PATCH 21/22] test: add stackTrace test and improve test descriptions --- packages/util/test/errors.spec.ts | 36 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/util/test/errors.spec.ts b/packages/util/test/errors.spec.ts index 4cc3d7a6aa..1a32692240 100644 --- a/packages/util/test/errors.spec.ts +++ b/packages/util/test/errors.spec.ts @@ -4,7 +4,7 @@ import { ErrorLogger } from '../src/errors' tape('ErrorLogger', (t) => { const errorLog = new ErrorLogger() - t.test('should assign the UNKNOWN_ERROR code to errors with undefined code', (st) => { + t.test('should assign the UNKNOWN_ERROR code to errors without code', (st) => { let error: any try { @@ -16,6 +16,18 @@ tape('ErrorLogger', (t) => { st.equal(error.code, ErrorLogger.errors.UNKNOWN_ERROR) st.end() }), + t.test('should preserve the stack trace of the throwError context', (st) => { + let error: any + + try { + errorLog.throwError() + } catch (e) { + error = e + } + + st.ok(/Error: {2}\| Details: code=UNKNOWN_ERROR\n {4}at Test./.test(error.stack)) + st.end() + }), t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { let error: any @@ -28,26 +40,12 @@ tape('ErrorLogger', (t) => { error = e } + st.equal(error.code, ErrorLogger.errors.UNKNOWN_ERROR) st.equal(error.errorInfo1, 'Information on the error') st.equal(error.errorInfo2, 'More information on the error') st.end() - }) - t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { - let error: any - - try { - errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { - errorInfo1: 'Information on the error', - errorInfo2: 'More information on the error', - }) - } catch (e) { - error = e - } - - st.equal(error.code, ErrorLogger.errors.UNKNOWN_ERROR) - st.end() - }), - t.test('should add all error params to error message details', (st) => { + }), + t.test('should add all error params of UNKNOWN_ERROR to error message details', (st) => { let error: any try { @@ -65,7 +63,7 @@ tape('ErrorLogger', (t) => { ) st.end() }), - t.test('should append all error params to existing error message', (st) => { + t.test('should append all error details to provided error message', (st) => { let error: any try { From 30f8eec54a40bf7b1f748c2b3ad759e4ed2cb6a4 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Mon, 21 Feb 2022 17:50:29 -0500 Subject: [PATCH 22/22] fix: handle case where Error.captureStackTrace is not defined --- packages/util/src/errors.ts | 5 +++- packages/util/test/errors.spec.ts | 44 ++++++++++++++++++------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts index 92ebd1a051..45dc7133d0 100644 --- a/packages/util/src/errors.ts +++ b/packages/util/src/errors.ts @@ -78,7 +78,10 @@ export class ErrorLogger { error[typedKey] = codedError[typedKey] }) - Error.captureStackTrace(error, this.throwError) + // captureStackTrace is not defined in some browsers, notably Firefox + if (Error.captureStackTrace) { + Error.captureStackTrace(error, this.throwError) + } throw error } diff --git a/packages/util/test/errors.spec.ts b/packages/util/test/errors.spec.ts index 1a32692240..3621c38ffe 100644 --- a/packages/util/test/errors.spec.ts +++ b/packages/util/test/errors.spec.ts @@ -25,7 +25,12 @@ tape('ErrorLogger', (t) => { error = e } - st.ok(/Error: {2}\| Details: code=UNKNOWN_ERROR\n {4}at Test./.test(error.stack)) + // captureStackTrace is not defined in some browsers, notably Firefox, so behavior can't be implemented/tested there + // @ts-ignore + if (Error.captureStackTrace) { + st.ok(/Error: {2}\| Details: code=UNKNOWN_ERROR\n {4}at Test./.test(error.stack)) + } + st.end() }), t.test('should populate an error with UNKNOWN_ERROR code with all provided params', (st) => { @@ -45,24 +50,27 @@ tape('ErrorLogger', (t) => { st.equal(error.errorInfo2, 'More information on the error') st.end() }), - t.test('should add all error params of UNKNOWN_ERROR to error message details', (st) => { - let error: any - - try { - errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { - errorInfo1: 'Information on the error', - errorInfo2: 'More information on the error', - }) - } catch (e) { - error = e + t.test( + 'should add all error params of UNKNOWN_ERROR to error mes21 02 2022 17:42:12.866:ERROR [launcher]: No binary for ChromeHeadless browser on your platform.sage details', + (st) => { + let error: any + + try { + errorLog.throwError(ErrorLogger.errors.UNKNOWN_ERROR, { + errorInfo1: 'Information on the error', + errorInfo2: 'More information on the error', + }) + } catch (e) { + error = e + } + + st.equal( + error.message, + ' | Details: errorInfo1="Information on the error", errorInfo2="More information on the error", code=UNKNOWN_ERROR' + ) + st.end() } - - st.equal( - error.message, - ' | Details: errorInfo1="Information on the error", errorInfo2="More information on the error", code=UNKNOWN_ERROR' - ) - st.end() - }), + ), t.test('should append all error details to provided error message', (st) => { let error: any