aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2017-11-11 03:13:15 +0800
committerFabio Berger <me@fabioberger.com>2017-11-11 03:13:15 +0800
commit4262ac3c8966468b343c6467e0e9da85ef25be05 (patch)
treebf57b46afd2967b72fc3cd6d5d11d8efa82fb3af
parent76b66872d8f797ee3b0efe0fa2ca914cf44ee46c (diff)
downloaddexon-0x-contracts-4262ac3c8966468b343c6467e0e9da85ef25be05.tar.gz
dexon-0x-contracts-4262ac3c8966468b343c6467e0e9da85ef25be05.tar.zst
dexon-0x-contracts-4262ac3c8966468b343c6467e0e9da85ef25be05.zip
Fix unhandled promise rejection error on subscriptions
-rw-r--r--src/contract_wrappers/contract_wrapper.ts25
-rw-r--r--src/types.ts4
-rw-r--r--test/exchange_wrapper_test.ts23
-rw-r--r--test/token_wrapper_test.ts10
4 files changed, 38 insertions, 24 deletions
diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts
index 19dccc6f2..a02465982 100644
--- a/src/contract_wrappers/contract_wrapper.ts
+++ b/src/contract_wrappers/contract_wrapper.ts
@@ -50,10 +50,14 @@ export class ContractWrapper {
this._filterCallbacks[filterToken] = callback;
return filterToken;
}
- protected _unsubscribe(filterToken: string): void {
+ protected _unsubscribe(filterToken: string, err?: Error): void {
if (_.isUndefined(this._filters[filterToken])) {
throw new Error(ZeroExError.SubscriptionNotFound);
}
+ if (!_.isUndefined(err)) {
+ const callback = this._filterCallbacks[filterToken];
+ callback(err, undefined);
+ }
delete this._filters[filterToken];
delete this._filterCallbacks[filterToken];
if (_.isEmpty(this._filters)) {
@@ -90,7 +94,7 @@ export class ContractWrapper {
...decodedLog,
removed,
};
- this._filterCallbacks[filterToken](logEvent);
+ this._filterCallbacks[filterToken](null, logEvent);
}
});
}
@@ -122,11 +126,18 @@ export class ContractWrapper {
delete this._blockAndLogStreamer;
}
private async _reconcileBlockAsync(): Promise<void> {
- const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
- // We need to coerce to Block type cause Web3.Block includes types for mempool blocks
- if (!_.isUndefined(this._blockAndLogStreamer)) {
- // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
- this._blockAndLogStreamer.reconcileNewBlock(latestBlock as any as Block);
+ try {
+ const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
+ // We need to coerce to Block type cause Web3.Block includes types for mempool blocks
+ if (!_.isUndefined(this._blockAndLogStreamer)) {
+ // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
+ this._blockAndLogStreamer.reconcileNewBlock(latestBlock as any as Block);
+ }
+ } catch (err) {
+ const filterTokens = _.keys(this._filterCallbacks);
+ _.each(filterTokens, filterToken => {
+ this._unsubscribe(filterToken, err);
+ });
}
}
}
diff --git a/src/types.ts b/src/types.ts
index a9eac56d8..af3c36736 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -41,8 +41,8 @@ export type OrderValues = [BigNumber, BigNumber, BigNumber,
export interface LogEvent<ArgsType> extends LogWithDecodedArgs<ArgsType> {
removed: boolean;
}
-export type EventCallbackAsync<ArgsType> = (log: LogEvent<ArgsType>) => Promise<void>;
-export type EventCallbackSync<ArgsType> = (log: LogEvent<ArgsType>) => void;
+export type EventCallbackAsync<ArgsType> = (err: null|Error, log?: LogEvent<ArgsType>) => Promise<void>;
+export type EventCallbackSync<ArgsType> = (err: null|Error, log?: LogEvent<ArgsType>) => void;
export type EventCallback<ArgsType> = EventCallbackSync<ArgsType>|EventCallbackAsync<ArgsType>;
export interface ExchangeContract extends Web3.ContractInstance {
isValidSignature: {
diff --git a/test/exchange_wrapper_test.ts b/test/exchange_wrapper_test.ts
index 7c76499d5..654f626c6 100644
--- a/test/exchange_wrapper_test.ts
+++ b/test/exchange_wrapper_test.ts
@@ -304,11 +304,11 @@ describe('ExchangeWrapper', () => {
orderFillBatch = [
{
signedOrder,
- takerTokenFillAmount: takerTokenFillAmount,
+ takerTokenFillAmount,
},
{
signedOrder: anotherSignedOrder,
- takerTokenFillAmount: takerTokenFillAmount,
+ takerTokenFillAmount,
},
];
});
@@ -647,7 +647,7 @@ describe('ExchangeWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
(async () => {
- const callback = (logEvent: LogEvent<LogFillContractEventArgs>) => {
+ const callback = (err: Error, logEvent: LogEvent<LogFillContractEventArgs>) => {
expect(logEvent.event).to.be.equal(ExchangeEvents.LogFill);
done();
};
@@ -655,13 +655,14 @@ describe('ExchangeWrapper', () => {
ExchangeEvents.LogFill, indexFilterValues, callback,
);
await zeroEx.exchange.fillOrderAsync(
- signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
+ signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
);
})().catch(done);
});
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
(async () => {
- const callback = (logEvent: LogEvent<LogCancelContractEventArgs>) => {
+ const callback = (err: Error, logEvent: LogEvent<LogCancelContractEventArgs>) => {
expect(logEvent.event).to.be.equal(ExchangeEvents.LogCancel);
done();
};
@@ -673,7 +674,7 @@ describe('ExchangeWrapper', () => {
});
it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (logEvent: LogEvent<LogFillContractEventArgs>) => {
+ const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent<LogFillContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
};
await zeroEx.exchange.subscribeAsync(
@@ -683,7 +684,7 @@ describe('ExchangeWrapper', () => {
const newProvider = web3Factory.getRpcProvider();
await zeroEx.setProviderAsync(newProvider);
- const callback = (logEvent: LogEvent<LogFillContractEventArgs>) => {
+ const callback = (err: Error, logEvent: LogEvent<LogFillContractEventArgs>) => {
expect(logEvent.event).to.be.equal(ExchangeEvents.LogFill);
done();
};
@@ -691,13 +692,14 @@ describe('ExchangeWrapper', () => {
ExchangeEvents.LogFill, indexFilterValues, callback,
);
await zeroEx.exchange.fillOrderAsync(
- signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
+ signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
);
})().catch(done);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (logEvent: LogEvent<LogFillContractEventArgs>) => {
+ const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent<LogFillContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
};
const subscriptionToken = await zeroEx.exchange.subscribeAsync(
@@ -705,7 +707,8 @@ describe('ExchangeWrapper', () => {
);
zeroEx.exchange.unsubscribe(subscriptionToken);
await zeroEx.exchange.fillOrderAsync(
- signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
+ signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
);
done();
})().catch(done);
diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts
index b35fa43f9..b244e3a92 100644
--- a/test/token_wrapper_test.ts
+++ b/test/token_wrapper_test.ts
@@ -358,7 +358,7 @@ describe('TokenWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
- const callback = (logEvent: LogEvent<TransferContractEventArgs>) => {
+ const callback = (err: Error, logEvent: LogEvent<TransferContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
const args = logEvent.args;
expect(args._from).to.be.equal(coinbase);
@@ -373,7 +373,7 @@ describe('TokenWrapper', () => {
});
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
- const callback = (logEvent: LogEvent<ApprovalContractEventArgs>) => {
+ const callback = (err: Error, logEvent: LogEvent<ApprovalContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
const args = logEvent.args;
expect(args._owner).to.be.equal(coinbase);
@@ -388,13 +388,13 @@ describe('TokenWrapper', () => {
});
it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (logEvent: LogEvent<TransferContractEventArgs>) => {
+ const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent<TransferContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
};
zeroEx.token.subscribe(
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
);
- const callbackToBeCalled = (logEvent: LogEvent<TransferContractEventArgs>) => {
+ const callbackToBeCalled = (err: Error, logEvent: LogEvent<TransferContractEventArgs>) => {
done();
};
const newProvider = web3Factory.getRpcProvider();
@@ -407,7 +407,7 @@ describe('TokenWrapper', () => {
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (logEvent: LogEvent<TokenContractEventArgs>) => {
+ const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent<TokenContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
};
const subscriptionToken = zeroEx.token.subscribe(