From 4262ac3c8966468b343c6467e0e9da85ef25be05 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 10 Nov 2017 14:13:15 -0500 Subject: Fix unhandled promise rejection error on subscriptions --- src/contract_wrappers/contract_wrapper.ts | 25 ++++++++++++++++++------- src/types.ts | 4 ++-- test/exchange_wrapper_test.ts | 23 +++++++++++++---------- test/token_wrapper_test.ts | 10 +++++----- 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 { - 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 extends LogWithDecodedArgs { removed: boolean; } -export type EventCallbackAsync = (log: LogEvent) => Promise; -export type EventCallbackSync = (log: LogEvent) => void; +export type EventCallbackAsync = (err: null|Error, log?: LogEvent) => Promise; +export type EventCallbackSync = (err: null|Error, log?: LogEvent) => void; export type EventCallback = EventCallbackSync|EventCallbackAsync; 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) => { + const callback = (err: Error, logEvent: LogEvent) => { 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) => { + const callback = (err: Error, logEvent: LogEvent) => { 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) => { + const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent) => { 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) => { + const callback = (err: Error, logEvent: LogEvent) => { 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) => { + const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent) => { 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) => { + const callback = (err: Error, logEvent: LogEvent) => { 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) => { + const callback = (err: Error, logEvent: LogEvent) => { 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) => { + const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }; zeroEx.token.subscribe( tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled, ); - const callbackToBeCalled = (logEvent: LogEvent) => { + const callbackToBeCalled = (err: Error, logEvent: LogEvent) => { 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) => { + const callbackNeverToBeCalled = (err: Error, logEvent: LogEvent) => { done(new Error('Expected this subscription to have been cancelled')); }; const subscriptionToken = zeroEx.token.subscribe( -- cgit v1.2.3 From 4ae9482d506ccdf028fcd39bbaf652bbcbef52e8 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 11 Nov 2017 11:01:59 -0500 Subject: Clean up subscription state. In the case of an exception, keep the state correct between contract wrapper, exchange wrapper and token wrapper. --- src/contract_wrappers/contract_wrapper.ts | 6 ++ src/contract_wrappers/exchange_wrapper.ts | 18 +++--- src/contract_wrappers/token_wrapper.ts | 7 +-- test/subscription_test.ts | 93 +++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 17 deletions(-) create mode 100644 test/subscription_test.ts diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index a02465982..5bdc66b3b 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -50,6 +50,12 @@ export class ContractWrapper { this._filterCallbacks[filterToken] = callback; return filterToken; } + protected unsubscribeAll(): void { + const filterTokens = _.keys(this._filterCallbacks); + _.each(filterTokens, filterToken => { + this._unsubscribe(filterToken); + }); + } protected _unsubscribe(filterToken: string, err?: Error): void { if (_.isUndefined(this._filters[filterToken])) { throw new Error(ZeroExError.SubscriptionNotFound); diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index b8704e72c..4fd2b23a8 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -49,7 +49,6 @@ const SHOULD_VALIDATE_BY_DEFAULT = true; */ export class ExchangeWrapper extends ContractWrapper { private _exchangeContractIfExists?: ExchangeContract; - private _activeSubscriptions: string[]; private _orderValidationUtils: OrderValidationUtils; private _tokenWrapper: TokenWrapper; private _exchangeContractErrCodesToMsg = { @@ -84,7 +83,6 @@ export class ExchangeWrapper extends ContractWrapper { super(web3Wrapper, abiDecoder); this._tokenWrapper = tokenWrapper; this._orderValidationUtils = new OrderValidationUtils(tokenWrapper, this); - this._activeSubscriptions = []; this._contractAddressIfExists = contractAddressIfExists; } /** @@ -666,7 +664,6 @@ export class ExchangeWrapper extends ContractWrapper { const subscriptionToken = this._subscribe( exchangeContractAddress, eventName, indexFilterValues, artifacts.ExchangeArtifact.abi, callback, ); - this._activeSubscriptions.push(subscriptionToken); return subscriptionToken; } /** @@ -674,9 +671,14 @@ export class ExchangeWrapper extends ContractWrapper { * @param subscriptionToken Subscription token returned by `subscribe()` */ public unsubscribe(subscriptionToken: string): void { - _.pull(this._activeSubscriptions, subscriptionToken); this._unsubscribe(subscriptionToken); } + /** + * Cancels all existing subscriptions + */ + public unsubscribeAll(): void { + super.unsubscribeAll(); + } /** * Gets historical logs without creating a subscription * @param eventName The exchange contract event you would like to subscribe to. @@ -825,13 +827,7 @@ export class ExchangeWrapper extends ContractWrapper { const ZRXtokenAddress = await exchangeInstance.ZRX_TOKEN_CONTRACT.callAsync(); return ZRXtokenAddress; } - /** - * Cancels all existing subscriptions - */ - public unsubscribeAll(): void { - _.forEach(this._activeSubscriptions, this._unsubscribe.bind(this)); - this._activeSubscriptions = []; - } + private async _invalidateContractInstancesAsync(): Promise { this.unsubscribeAll(); delete this._exchangeContractIfExists; diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index 5d6d61cef..fbe7354dc 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -29,13 +29,11 @@ const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 47275; export class TokenWrapper extends ContractWrapper { public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; private _tokenContractsByAddress: {[address: string]: TokenContract}; - private _activeSubscriptions: string[]; private _tokenTransferProxyContractAddressFetcher: () => Promise; constructor(web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, tokenTransferProxyContractAddressFetcher: () => Promise) { super(web3Wrapper, abiDecoder); this._tokenContractsByAddress = {}; - this._activeSubscriptions = []; this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher; } /** @@ -262,7 +260,6 @@ export class TokenWrapper extends ContractWrapper { const subscriptionToken = this._subscribe( tokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, callback, ); - this._activeSubscriptions.push(subscriptionToken); return subscriptionToken; } /** @@ -270,7 +267,6 @@ export class TokenWrapper extends ContractWrapper { * @param subscriptionToken Subscription token returned by `subscribe()` */ public unsubscribe(subscriptionToken: string): void { - _.pull(this._activeSubscriptions, subscriptionToken); this._unsubscribe(subscriptionToken); } /** @@ -298,8 +294,7 @@ export class TokenWrapper extends ContractWrapper { * Cancels all existing subscriptions */ public unsubscribeAll(): void { - _.forEach(this._activeSubscriptions, this._unsubscribe.bind(this)); - this._activeSubscriptions = []; + super.unsubscribeAll(); } private _invalidateContractInstancesAsync(): void { this.unsubscribeAll(); diff --git a/test/subscription_test.ts b/test/subscription_test.ts new file mode 100644 index 000000000..d328084af --- /dev/null +++ b/test/subscription_test.ts @@ -0,0 +1,93 @@ +import 'mocha'; +import * as chai from 'chai'; +import * as Sinon from 'sinon'; +import {chaiSetup} from './utils/chai_setup'; +import * as Web3 from 'web3'; +import BigNumber from 'bignumber.js'; +import promisify = require('es6-promisify'); +import {web3Factory} from './utils/web3_factory'; +import { + ZeroEx, + ZeroExError, + Token, + SubscriptionOpts, + TokenEvents, + ContractEvent, + TransferContractEventArgs, + ApprovalContractEventArgs, + TokenContractEventArgs, + LogWithDecodedArgs, + LogEvent, +} from '../src'; +import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; +import {TokenUtils} from './utils/token_utils'; +import {DoneCallback, BlockParamLiteral} from '../src/types'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(); + +describe('SubscriptionTest', () => { + let web3: Web3; + let zeroEx: ZeroEx; + let userAddresses: string[]; + let tokens: Token[]; + let tokenUtils: TokenUtils; + let coinbase: string; + let addressWithoutFunds: string; + before(async () => { + web3 = web3Factory.create(); + zeroEx = new ZeroEx(web3.currentProvider); + userAddresses = await zeroEx.getAvailableAddressesAsync(); + tokens = await zeroEx.tokenRegistry.getTokensAsync(); + tokenUtils = new TokenUtils(tokens); + coinbase = userAddresses[0]; + addressWithoutFunds = userAddresses[1]; + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + + describe('#subscribe', () => { + const indexFilterValues = {}; + const shouldThrowOnInsufficientBalanceOrAllowance = true; + let tokenAddress: string; + const transferAmount = new BigNumber(42); + const allowanceAmount = new BigNumber(42); + before(() => { + const token = tokens[0]; + tokenAddress = token.address; + }); + afterEach(() => { + zeroEx.token.unsubscribeAll(); + }); + it('Should receive the Error when an error occurs', (done: DoneCallback) => { + (async () => { + const callback = (err: Error, logEvent: LogEvent) => { + expect(err).to.not.be.undefined(); + expect(logEvent).to.be.undefined(); + done(); + }; + Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync') + .throws("JSON RPC error") + zeroEx.token.subscribe( + tokenAddress, TokenEvents.Approval, indexFilterValues, callback); + await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); + })().catch(done); + }); + it('Should allow unsubscribeAll to be called multiple times', (done: DoneCallback) => { + (async () => { + const callback = (err: Error, logEvent: LogEvent) => { }; + zeroEx.token.subscribe( + tokenAddress, TokenEvents.Approval, indexFilterValues, callback); + await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); + zeroEx.token.unsubscribeAll(); + zeroEx.token.unsubscribeAll(); + done(); + })().catch(done); + }); + }) + }) \ No newline at end of file -- cgit v1.2.3 From a85b1f016d96b1706dcea07aa2581a47035ba7db Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 11 Nov 2017 12:01:27 -0500 Subject: Test case was error then unsubscribe --- test/subscription_test.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/subscription_test.ts b/test/subscription_test.ts index d328084af..9a2198e10 100644 --- a/test/subscription_test.ts +++ b/test/subscription_test.ts @@ -1,4 +1,5 @@ import 'mocha'; +import * as _ from 'lodash'; import * as chai from 'chai'; import * as Sinon from 'sinon'; import {chaiSetup} from './utils/chai_setup'; @@ -57,12 +58,15 @@ describe('SubscriptionTest', () => { let tokenAddress: string; const transferAmount = new BigNumber(42); const allowanceAmount = new BigNumber(42); + let stubs: Sinon.SinonStub[] = []; before(() => { const token = tokens[0]; tokenAddress = token.address; }); afterEach(() => { zeroEx.token.unsubscribeAll(); + _.each(stubs, s => s.restore()); + stubs = []; }); it('Should receive the Error when an error occurs', (done: DoneCallback) => { (async () => { @@ -71,20 +75,25 @@ describe('SubscriptionTest', () => { expect(logEvent).to.be.undefined(); done(); }; - Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync') - .throws("JSON RPC error") + stubs = [ + Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync') + .throws("JSON RPC error") + ] zeroEx.token.subscribe( tokenAddress, TokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); })().catch(done); }); - it('Should allow unsubscribeAll to be called multiple times', (done: DoneCallback) => { + it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => { (async () => { const callback = (err: Error, logEvent: LogEvent) => { }; zeroEx.token.subscribe( tokenAddress, TokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); - zeroEx.token.unsubscribeAll(); + stubs = [ + Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync') + .throws("JSON RPC error") + ] zeroEx.token.unsubscribeAll(); done(); })().catch(done); -- cgit v1.2.3 From 394417ff073c54ba7409ac24004a9757935688cb Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 11 Nov 2017 12:15:24 -0500 Subject: Removed nits --- src/contract_wrappers/exchange_wrapper.ts | 1 - test/subscription_test.ts | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 4fd2b23a8..711d883ef 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -827,7 +827,6 @@ export class ExchangeWrapper extends ContractWrapper { const ZRXtokenAddress = await exchangeInstance.ZRX_TOKEN_CONTRACT.callAsync(); return ZRXtokenAddress; } - private async _invalidateContractInstancesAsync(): Promise { this.unsubscribeAll(); delete this._exchangeContractIfExists; diff --git a/test/subscription_test.ts b/test/subscription_test.ts index 9a2198e10..64e9acf0d 100644 --- a/test/subscription_test.ts +++ b/test/subscription_test.ts @@ -11,13 +11,8 @@ import { ZeroEx, ZeroExError, Token, - SubscriptionOpts, - TokenEvents, - ContractEvent, - TransferContractEventArgs, ApprovalContractEventArgs, - TokenContractEventArgs, - LogWithDecodedArgs, + TokenEvents, LogEvent, } from '../src'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; @@ -51,7 +46,6 @@ describe('SubscriptionTest', () => { afterEach(async () => { await blockchainLifecycle.revertAsync(); }); - describe('#subscribe', () => { const indexFilterValues = {}; const shouldThrowOnInsufficientBalanceOrAllowance = true; @@ -72,6 +66,7 @@ describe('SubscriptionTest', () => { (async () => { const callback = (err: Error, logEvent: LogEvent) => { expect(err).to.not.be.undefined(); + expect(err).to.not.be.null(); expect(logEvent).to.be.undefined(); done(); }; @@ -89,7 +84,6 @@ describe('SubscriptionTest', () => { const callback = (err: Error, logEvent: LogEvent) => { }; zeroEx.token.subscribe( tokenAddress, TokenEvents.Approval, indexFilterValues, callback); - await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); stubs = [ Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync') .throws("JSON RPC error") -- cgit v1.2.3 From ee73659f16dd70f15fa883e8d512e0da893b1393 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 11 Nov 2017 12:33:05 -0500 Subject: Check for null rather than undefined --- test/subscription_test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/subscription_test.ts b/test/subscription_test.ts index 64e9acf0d..985fdc1d6 100644 --- a/test/subscription_test.ts +++ b/test/subscription_test.ts @@ -65,7 +65,6 @@ describe('SubscriptionTest', () => { it('Should receive the Error when an error occurs', (done: DoneCallback) => { (async () => { const callback = (err: Error, logEvent: LogEvent) => { - expect(err).to.not.be.undefined(); expect(err).to.not.be.null(); expect(logEvent).to.be.undefined(); done(); -- cgit v1.2.3 From d34ea79d939beaf677c6730fe6e84e25a687d59f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 11 Nov 2017 13:42:42 -0500 Subject: Push unsubscribe to the base class rather than super --- src/contract_wrappers/contract_wrapper.ts | 29 ++++++++++++++++------------- src/contract_wrappers/exchange_wrapper.ts | 6 ------ src/contract_wrappers/token_wrapper.ts | 6 ------ 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 5bdc66b3b..7997b1647 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -38,19 +38,10 @@ export class ContractWrapper { this._onLogAddedSubscriptionToken = undefined; this._onLogRemovedSubscriptionToken = undefined; } - protected _subscribe( - address: string, eventName: ContractEvents, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi, - callback: EventCallback): string { - const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi); - if (_.isUndefined(this._blockAndLogStreamer)) { - this._startBlockAndLogStream(); - } - const filterToken = filterUtils.generateUUID(); - this._filters[filterToken] = filter; - this._filterCallbacks[filterToken] = callback; - return filterToken; - } - protected unsubscribeAll(): void { + /** + * Cancels all existing subscriptions + */ + public unsubscribeAll(): void { const filterTokens = _.keys(this._filterCallbacks); _.each(filterTokens, filterToken => { this._unsubscribe(filterToken); @@ -70,6 +61,18 @@ export class ContractWrapper { this._stopBlockAndLogStream(); } } + protected _subscribe( + address: string, eventName: ContractEvents, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi, + callback: EventCallback): string { + const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi); + if (_.isUndefined(this._blockAndLogStreamer)) { + this._startBlockAndLogStream(); + } + const filterToken = filterUtils.generateUUID(); + this._filters[filterToken] = filter; + this._filterCallbacks[filterToken] = callback; + return filterToken; + } protected async _getLogsAsync( address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise>> { diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 711d883ef..b608e6931 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -673,12 +673,6 @@ export class ExchangeWrapper extends ContractWrapper { public unsubscribe(subscriptionToken: string): void { this._unsubscribe(subscriptionToken); } - /** - * Cancels all existing subscriptions - */ - public unsubscribeAll(): void { - super.unsubscribeAll(); - } /** * Gets historical logs without creating a subscription * @param eventName The exchange contract event you would like to subscribe to. diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index fbe7354dc..081113964 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -290,12 +290,6 @@ export class TokenWrapper extends ContractWrapper { ); return logs; } - /** - * Cancels all existing subscriptions - */ - public unsubscribeAll(): void { - super.unsubscribeAll(); - } private _invalidateContractInstancesAsync(): void { this.unsubscribeAll(); this._tokenContractsByAddress = {}; -- cgit v1.2.3 From e57a507ba0241061f42bf9796c4bc0e8472b9289 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 12 Nov 2017 10:39:09 -0500 Subject: Update testRPC snapshot used by CircleCi --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 5a8d340f0..3dc00bd03 100644 --- a/circle.yml +++ b/circle.yml @@ -2,7 +2,7 @@ machine: node: version: 6.5.0 environment: - CONTRACTS_COMMIT_HASH: '35053f9' + CONTRACTS_COMMIT_HASH: '78fe8dd' PATH: "${PATH}:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin" dependencies: -- cgit v1.2.3 From dae5a063cf1568676485d4dc0a0d97f0e7aa5daa Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 12 Nov 2017 10:43:24 -0500 Subject: Fix amounts in tests one last time. Now that we updated the testRPC snapshot, this should no longer be mismatched between CI and locally --- test/token_wrapper_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts index b244e3a92..d9d0fb9ad 100644 --- a/test/token_wrapper_test.ts +++ b/test/token_wrapper_test.ts @@ -161,7 +161,7 @@ describe('TokenWrapper', () => { const token = tokens[0]; const ownerAddress = coinbase; const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress); - const expectedBalance = new BigNumber('100000000000000000000000000'); + const expectedBalance = new BigNumber('1000000000000000000000000000'); return expect(balance).to.be.bignumber.equal(expectedBalance); }); it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => { @@ -189,7 +189,7 @@ describe('TokenWrapper', () => { const token = tokens[0]; const ownerAddress = coinbase; const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress); - const expectedBalance = new BigNumber('100000000000000000000000000'); + const expectedBalance = new BigNumber('1000000000000000000000000000'); return expect(balance).to.be.bignumber.equal(expectedBalance); }); }); -- cgit v1.2.3 From d4cab6e62f1d96923c99cf58bcfd3b2392b35a30 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 12 Nov 2017 16:57:13 -0500 Subject: Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 029144b5a..00164bb74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +v0.23.0 - _November 12, 2017_ +------------------------ + * Fixed unhandled promise rejection error in subscribe methods (#209) + * Subscribe callbacks now receive an error object as their first argument + v0.22.6 - _November 10, 2017_ ------------------------ * Add a timeout parameter to transaction awaiting (#206) -- cgit v1.2.3 From 1392a855bb17981f7680548a23062842fb6dc4e0 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 12 Nov 2017 17:01:58 -0500 Subject: 0.23.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b4a97d87..8e2823103 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "0.22.6", + "version": "0.23.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f8aed6436..1f4c2de5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "0.22.6", + "version": "0.23.0", "description": "A javascript library for interacting with the 0x protocol", "keywords": [ "0x.js", -- cgit v1.2.3