Skip to content

Commit

Permalink
6306 allEvents bug fix (#6346)
Browse files Browse the repository at this point in the history
* fix ALL_EVENTS bug and optimization

* test and changelog

* failed event reject with inner error and its test

* changelog update
  • Loading branch information
jdevcs committed Aug 15, 2023
1 parent f4fd498 commit c41d356
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
8 changes: 8 additions & 0 deletions packages/web3-eth-contract/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,11 @@ Documentation:
- Dependencies updated

## [Unreleased]

### Fixed

- Fixed bug in `contract.events.allEvents`

### Added

- In case of error events there will be inner error also available for details
18 changes: 10 additions & 8 deletions packages/web3-eth-contract/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import {
ValidationSchemaInput,
Web3ValidatorError,
} from 'web3-validator';
import { ALL_EVENTS_ABI } from './constants.js';
import { ALL_EVENTS, ALL_EVENTS_ABI } from './constants.js';
import { decodeEventABI, decodeMethodReturn, encodeEventABI, encodeMethodABI } from './encoding.js';
import { LogsSubscription } from './log_subscription.js';
import {
Expand Down Expand Up @@ -718,7 +718,7 @@ export class Contract<Abi extends ContractAbi>
: param3 ?? DEFAULT_RETURN_FORMAT;

const abi =
eventName === 'allEvents'
eventName === 'allEvents' || eventName === ALL_EVENTS
? ALL_EVENTS_ABI
: (this._jsonInterface.find(
j => 'name' in j && j.name === eventName,
Expand Down Expand Up @@ -856,11 +856,10 @@ export class Contract<Abi extends ContractAbi>
this._events[eventSignature as keyof ContractEventsInterface<Abi>] = event as never;
}

this._events.allEvents = this._createContractEvent(ALL_EVENTS_ABI, returnFormat);

result = [...result, abi];
}

this._events.allEvents = this._createContractEvent(ALL_EVENTS_ABI, returnFormat);
this._jsonInterface = [...result] as unknown as ContractAbiWithSignature;
this._errorsInterface = errorsAbi;
}
Expand Down Expand Up @@ -1161,12 +1160,15 @@ export class Contract<Abi extends ContractAbi>
.then(logs => {
logs.forEach(log => sub.emit('data', log as EventLog));
})
.catch(() => {
sub.emit('error', new SubscriptionError('Failed to get past events.'));
.catch((error: Error) => {
sub.emit(
'error',
new SubscriptionError('Failed to get past events.', error),
);
});
}
this.subscriptionManager?.addSubscription(sub).catch(() => {
sub.emit('error', new SubscriptionError('Failed to subscribe.'));
this.subscriptionManager?.addSubscription(sub).catch((error: Error) => {
sub.emit('error', new SubscriptionError('Failed to subscribe.', error));
});

return sub;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,48 @@ describe('contract', () => {
).toHaveLength(2);
});
});

describeIf(isWs)('allEvents', () => {
it('should sub and get event using earliest options with allEvents()', async () => {
// eslint-disable-next-line jest/no-standalone-expect
return expect(
processAsync(async (resolve, reject) => {
const event = contractDeployed.events.allEvents({ fromBlock: 'earliest' });

event.on('data', resolve);
event.on('error', reject);

// trigger event
await contractDeployed.methods
.firesMultiValueEvent('val test', 12, true)
.send(sendOptions);
}),
).resolves.toEqual(
expect.objectContaining({
event: 'MultiValueEvent',
}),
);
});

it('should sub allEvents()', async () => {
// eslint-disable-next-line jest/no-standalone-expect
return expect(
processAsync(async (resolve, reject) => {
const event = contractDeployed.events.allEvents();

event.on('data', resolve);
event.on('error', reject);

// trigger event
await contractDeployed.methods
.firesMultiValueEvent('Pak1', 12, true)
.send(sendOptions);
}),
).resolves.toEqual(
expect.objectContaining({
event: 'MultiValueEvent',
}),
);
});
});
});
41 changes: 41 additions & 0 deletions packages/web3-eth-contract/test/unit/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { AllGetPastEventsData, getLogsData, getPastEventsData } from '../fixture
import { getSystemTestProvider } from '../fixtures/system_test_utils';
import { erc721Abi } from '../fixtures/erc721';
import { ERC20TokenAbi } from '../shared_fixtures/build/ERC20Token';
import { processAsync } from '../shared_fixtures/utils';

jest.mock('web3-eth');

Expand Down Expand Up @@ -799,6 +800,46 @@ describe('Contract', () => {
spyGetLogs.mockClear();
});

it('allEvents() should throw error with inner error', async () => {
const contract = new Contract<typeof GreeterAbi>(GreeterAbi);

const spyTx = jest.spyOn(eth, 'sendTransaction').mockImplementation(() => {
const newContract = contract.clone();
newContract.options.address = deployedAddr;
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return Promise.resolve(newContract) as any;
});

const spyGetLogs = jest
.spyOn(eth, 'getLogs')
.mockImplementation((_objInstance, _params) => {
throw new Error('Inner error');
});

const deployedContract = await contract
.deploy({
data: GreeterBytecode,
arguments: ['My Greeting'],
})
.send(sendOptions);

await expect(
processAsync(async (resolve, reject) => {
const event = deployedContract.events.allEvents({ fromBlock: 'earliest' });

event.on('error', reject);
event.on('data', resolve);
}),
).rejects.toThrow(
expect.objectContaining({
innerError: expect.any(Error),
}),
);

spyTx.mockClear();
spyGetLogs.mockClear();
});

it('encodeABI should work for the deploy function', () => {
const contract = new Contract(GreeterAbi);

Expand Down

0 comments on commit c41d356

Please sign in to comment.