From 7af0818dffe67483491f99062071b582fba456cb Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Thu, 20 Dec 2018 15:31:13 -0800 Subject: Capture errors in next callbacks --- .../src/trace_collection_subprovider.ts | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 25e38768d..8b4ea82f5 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -20,6 +20,24 @@ export interface TraceCollectionSubproviderConfig { shouldCollectGasEstimateTraces: boolean; } +type AsyncFunc = (...args: any[]) => Promise; + +// This wrapper outputs errors to console even if the promise gets ignored +// we need this because web3-provider-engine does not handler promises in +// the after function of next(after). +function logErrors(fn: AsyncFunc): AsyncFunc { + async function wrapped(...args: any[]): Promise { + try { + await fn(...args); + } catch (e) { + // tslint:disable-next-line no-console + console.error(e); + throw e; + } + } + return wrapped; +} + // Because there is no notion of a call trace in the Ethereum rpc - we collect them in a rather non-obvious/hacky way. // On each call - we create a snapshot, execute the call as a transaction, get the trace, revert the snapshot. // That allows us to avoid influencing test behaviour. @@ -74,7 +92,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const txData = payload.params[0]; - next(this._onTransactionSentAsync.bind(this, txData)); + next(logErrors(this._onTransactionSentAsync.bind(this, txData))); } return; @@ -83,7 +101,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const callData = payload.params[0]; - next(this._onCallOrGasEstimateExecutedAsync.bind(this, callData)); + next(logErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, callData))); } return; @@ -92,7 +110,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const estimateGasData = payload.params[0]; - next(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData)); + next(logErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData))); } return; -- cgit v1.2.3 From 2b8f0d887ad529bb0557a55c67cc162977c7b270 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 14 Jan 2019 12:16:00 +0100 Subject: Fix linter --- packages/sol-tracing-utils/src/trace_collection_subprovider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 8b4ea82f5..3ae8566f9 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -26,7 +26,7 @@ type AsyncFunc = (...args: any[]) => Promise; // we need this because web3-provider-engine does not handler promises in // the after function of next(after). function logErrors(fn: AsyncFunc): AsyncFunc { - async function wrapped(...args: any[]): Promise { + async function wrappedAsync(...args: any[]): Promise { try { await fn(...args); } catch (e) { @@ -35,7 +35,7 @@ function logErrors(fn: AsyncFunc): AsyncFunc { throw e; } } - return wrapped; + return wrappedAsync; } // Because there is no notion of a call trace in the Ethereum rpc - we collect them in a rather non-obvious/hacky way. -- cgit v1.2.3 From ed3b89f0054677025e42483df720d59abce133b4 Mon Sep 17 00:00:00 2001 From: Fabio B Date: Mon, 14 Jan 2019 13:51:10 +0100 Subject: Update packages/sol-tracing-utils/src/trace_collection_subprovider.ts Co-Authored-By: LogvinovLeon --- packages/sol-tracing-utils/src/trace_collection_subprovider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 3ae8566f9..e3f5561aa 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -23,7 +23,7 @@ export interface TraceCollectionSubproviderConfig { type AsyncFunc = (...args: any[]) => Promise; // This wrapper outputs errors to console even if the promise gets ignored -// we need this because web3-provider-engine does not handler promises in +// we need this because web3-provider-engine does not handle promises in // the after function of next(after). function logErrors(fn: AsyncFunc): AsyncFunc { async function wrappedAsync(...args: any[]): Promise { -- cgit v1.2.3 From d9675ad6d3ca5e1c124c91d182cfbec9c912fb15 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 Jan 2019 11:48:04 +0100 Subject: Refactor logAsyncErrors to follow our conventions --- .../sol-tracing-utils/src/trace_collection_subprovider.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index e3f5561aa..d79c5ca22 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -1,4 +1,5 @@ import { BlockchainLifecycle } from '@0x/dev-utils'; +import { logUtils } from '@0x/utils'; import { Callback, ErrorCallback, NextCallback, Subprovider } from '@0x/subproviders'; import { CallDataRPC, marshaller, Web3Wrapper } from '@0x/web3-wrapper'; import { JSONRPCRequestPayload, Provider, TxData } from 'ethereum-types'; @@ -25,14 +26,14 @@ type AsyncFunc = (...args: any[]) => Promise; // This wrapper outputs errors to console even if the promise gets ignored // we need this because web3-provider-engine does not handle promises in // the after function of next(after). -function logErrors(fn: AsyncFunc): AsyncFunc { +function logAsyncErrors(fn: AsyncFunc): AsyncFunc { async function wrappedAsync(...args: any[]): Promise { try { await fn(...args); - } catch (e) { + } catch (err) { // tslint:disable-next-line no-console - console.error(e); - throw e; + logUtils.error(err); + throw err; } } return wrappedAsync; @@ -92,7 +93,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const txData = payload.params[0]; - next(logErrors(this._onTransactionSentAsync.bind(this, txData))); + next(logAsyncErrors(this._onTransactionSentAsync.bind(this, txData))); } return; @@ -101,7 +102,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const callData = payload.params[0]; - next(logErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, callData))); + next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, callData))); } return; @@ -110,7 +111,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const estimateGasData = payload.params[0]; - next(logErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData))); + next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData))); } return; -- cgit v1.2.3 From 7ea274b7316ddc40298a66278a14a735cfd314de Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 Jan 2019 11:55:06 +0100 Subject: Remove logAsyncErrors hack --- .../src/trace_collection_subprovider.ts | 78 ++++++++++------------ 1 file changed, 34 insertions(+), 44 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index d79c5ca22..a57ecaad3 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -21,24 +21,6 @@ export interface TraceCollectionSubproviderConfig { shouldCollectGasEstimateTraces: boolean; } -type AsyncFunc = (...args: any[]) => Promise; - -// This wrapper outputs errors to console even if the promise gets ignored -// we need this because web3-provider-engine does not handle promises in -// the after function of next(after). -function logAsyncErrors(fn: AsyncFunc): AsyncFunc { - async function wrappedAsync(...args: any[]): Promise { - try { - await fn(...args); - } catch (err) { - // tslint:disable-next-line no-console - logUtils.error(err); - throw err; - } - } - return wrappedAsync; -} - // Because there is no notion of a call trace in the Ethereum rpc - we collect them in a rather non-obvious/hacky way. // On each call - we create a snapshot, execute the call as a transaction, get the trace, revert the snapshot. // That allows us to avoid influencing test behaviour. @@ -93,7 +75,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const txData = payload.params[0]; - next(logAsyncErrors(this._onTransactionSentAsync.bind(this, txData))); + next(this._onTransactionSentAsync.bind(this, txData)); } return; @@ -102,7 +84,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const callData = payload.params[0]; - next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, callData))); + next(this._onCallOrGasEstimateExecutedAsync.bind(this, callData)); } return; @@ -111,7 +93,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const estimateGasData = payload.params[0]; - next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData))); + next(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData)); } return; @@ -145,31 +127,35 @@ export abstract class TraceCollectionSubprovider extends Subprovider { txHash: string | undefined, cb: Callback, ): Promise { - if (!txData.isFakeTransaction) { - // This transaction is a usual transaction. Not a call executed as one. - // And we don't want it to be executed within a snapshotting period - await this._lock.acquire(); - } - const NULL_ADDRESS = '0x0'; - if (_.isNull(err)) { - const toAddress = - _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; - await this._recordTxTraceAsync(toAddress, txData.data, txHash as string); - } else { - const latestBlock = await this._web3Wrapper.getBlockWithTransactionDataAsync(BlockParamLiteral.Latest); - const transactions = latestBlock.transactions; - for (const transaction of transactions) { + try { + if (!txData.isFakeTransaction) { + // This transaction is a usual transaction. Not a call executed as one. + // And we don't want it to be executed within a snapshotting period + await this._lock.acquire(); + } + const NULL_ADDRESS = '0x0'; + if (_.isNull(err)) { const toAddress = _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; - await this._recordTxTraceAsync(toAddress, transaction.input, transaction.hash); + await this._recordTxTraceAsync(toAddress, txData.data, txHash as string); + } else { + const latestBlock = await this._web3Wrapper.getBlockWithTransactionDataAsync(BlockParamLiteral.Latest); + const transactions = latestBlock.transactions; + for (const transaction of transactions) { + const toAddress = + _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; + await this._recordTxTraceAsync(toAddress, transaction.input, transaction.hash); + } } + if (!txData.isFakeTransaction) { + // This transaction is a usual transaction. Not a call executed as one. + // And we don't want it to be executed within a snapshotting period + this._lock.release(); + } + cb(); + } catch (err) { + cb(err); } - if (!txData.isFakeTransaction) { - // This transaction is a usual transaction. Not a call executed as one. - // And we don't want it to be executed within a snapshotting period - this._lock.release(); - } - cb(); } private async _onCallOrGasEstimateExecutedAsync( callData: Partial, @@ -177,8 +163,12 @@ export abstract class TraceCollectionSubprovider extends Subprovider { _callResult: string, cb: Callback, ): Promise { - await this._recordCallOrGasEstimateTraceAsync(callData); - cb(); + try { + await this._recordCallOrGasEstimateTraceAsync(callData); + cb(); + } catch (err) { + cb(err); + } } private async _recordCallOrGasEstimateTraceAsync(callData: Partial): Promise { // We don't want other transactions to be exeucted during snashotting period, that's why we lock the -- cgit v1.2.3 From c2ec4174b765d2f3352dd0fd8b04e4d2c1955d64 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 Jan 2019 12:09:17 +0100 Subject: Revert "Remove logAsyncErrors hack" This reverts commit 7ea274b7316ddc40298a66278a14a735cfd314de. --- .../src/trace_collection_subprovider.ts | 78 ++++++++++++---------- 1 file changed, 44 insertions(+), 34 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index a57ecaad3..d79c5ca22 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -21,6 +21,24 @@ export interface TraceCollectionSubproviderConfig { shouldCollectGasEstimateTraces: boolean; } +type AsyncFunc = (...args: any[]) => Promise; + +// This wrapper outputs errors to console even if the promise gets ignored +// we need this because web3-provider-engine does not handle promises in +// the after function of next(after). +function logAsyncErrors(fn: AsyncFunc): AsyncFunc { + async function wrappedAsync(...args: any[]): Promise { + try { + await fn(...args); + } catch (err) { + // tslint:disable-next-line no-console + logUtils.error(err); + throw err; + } + } + return wrappedAsync; +} + // Because there is no notion of a call trace in the Ethereum rpc - we collect them in a rather non-obvious/hacky way. // On each call - we create a snapshot, execute the call as a transaction, get the trace, revert the snapshot. // That allows us to avoid influencing test behaviour. @@ -75,7 +93,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const txData = payload.params[0]; - next(this._onTransactionSentAsync.bind(this, txData)); + next(logAsyncErrors(this._onTransactionSentAsync.bind(this, txData))); } return; @@ -84,7 +102,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const callData = payload.params[0]; - next(this._onCallOrGasEstimateExecutedAsync.bind(this, callData)); + next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, callData))); } return; @@ -93,7 +111,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { next(); } else { const estimateGasData = payload.params[0]; - next(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData)); + next(logAsyncErrors(this._onCallOrGasEstimateExecutedAsync.bind(this, estimateGasData))); } return; @@ -127,35 +145,31 @@ export abstract class TraceCollectionSubprovider extends Subprovider { txHash: string | undefined, cb: Callback, ): Promise { - try { - if (!txData.isFakeTransaction) { - // This transaction is a usual transaction. Not a call executed as one. - // And we don't want it to be executed within a snapshotting period - await this._lock.acquire(); - } - const NULL_ADDRESS = '0x0'; - if (_.isNull(err)) { + if (!txData.isFakeTransaction) { + // This transaction is a usual transaction. Not a call executed as one. + // And we don't want it to be executed within a snapshotting period + await this._lock.acquire(); + } + const NULL_ADDRESS = '0x0'; + if (_.isNull(err)) { + const toAddress = + _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; + await this._recordTxTraceAsync(toAddress, txData.data, txHash as string); + } else { + const latestBlock = await this._web3Wrapper.getBlockWithTransactionDataAsync(BlockParamLiteral.Latest); + const transactions = latestBlock.transactions; + for (const transaction of transactions) { const toAddress = _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; - await this._recordTxTraceAsync(toAddress, txData.data, txHash as string); - } else { - const latestBlock = await this._web3Wrapper.getBlockWithTransactionDataAsync(BlockParamLiteral.Latest); - const transactions = latestBlock.transactions; - for (const transaction of transactions) { - const toAddress = - _.isUndefined(txData.to) || txData.to === NULL_ADDRESS ? constants.NEW_CONTRACT : txData.to; - await this._recordTxTraceAsync(toAddress, transaction.input, transaction.hash); - } + await this._recordTxTraceAsync(toAddress, transaction.input, transaction.hash); } - if (!txData.isFakeTransaction) { - // This transaction is a usual transaction. Not a call executed as one. - // And we don't want it to be executed within a snapshotting period - this._lock.release(); - } - cb(); - } catch (err) { - cb(err); } + if (!txData.isFakeTransaction) { + // This transaction is a usual transaction. Not a call executed as one. + // And we don't want it to be executed within a snapshotting period + this._lock.release(); + } + cb(); } private async _onCallOrGasEstimateExecutedAsync( callData: Partial, @@ -163,12 +177,8 @@ export abstract class TraceCollectionSubprovider extends Subprovider { _callResult: string, cb: Callback, ): Promise { - try { - await this._recordCallOrGasEstimateTraceAsync(callData); - cb(); - } catch (err) { - cb(err); - } + await this._recordCallOrGasEstimateTraceAsync(callData); + cb(); } private async _recordCallOrGasEstimateTraceAsync(callData: Partial): Promise { // We don't want other transactions to be exeucted during snashotting period, that's why we lock the -- cgit v1.2.3 From 75a4bbc5f2bf38c2ea8c18f21dc9b54eaf5bb422 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 Jan 2019 12:09:48 +0100 Subject: Remove unused tslint disable --- packages/sol-tracing-utils/src/trace_collection_subprovider.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index d79c5ca22..2bbb4c62b 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -1,6 +1,6 @@ import { BlockchainLifecycle } from '@0x/dev-utils'; -import { logUtils } from '@0x/utils'; import { Callback, ErrorCallback, NextCallback, Subprovider } from '@0x/subproviders'; +import { logUtils } from '@0x/utils'; import { CallDataRPC, marshaller, Web3Wrapper } from '@0x/web3-wrapper'; import { JSONRPCRequestPayload, Provider, TxData } from 'ethereum-types'; import * as _ from 'lodash'; @@ -31,8 +31,7 @@ function logAsyncErrors(fn: AsyncFunc): AsyncFunc { try { await fn(...args); } catch (err) { - // tslint:disable-next-line no-console - logUtils.error(err); + logUtils.log(err); throw err; } } -- cgit v1.2.3 From 64d99dc07cc82c7cc2917871596b46985f1d709f Mon Sep 17 00:00:00 2001 From: Fabio B Date: Tue, 15 Jan 2019 14:44:52 +0100 Subject: Update packages/sol-tracing-utils/src/trace_collection_subprovider.ts Co-Authored-By: LogvinovLeon --- packages/sol-tracing-utils/src/trace_collection_subprovider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/sol-tracing-utils/src/trace_collection_subprovider.ts') diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 2bbb4c62b..323e1523c 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -23,7 +23,7 @@ export interface TraceCollectionSubproviderConfig { type AsyncFunc = (...args: any[]) => Promise; -// This wrapper outputs errors to console even if the promise gets ignored +// HACK: This wrapper outputs errors to console even if the promise gets ignored // we need this because web3-provider-engine does not handle promises in // the after function of next(after). function logAsyncErrors(fn: AsyncFunc): AsyncFunc { -- cgit v1.2.3