Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 866469d

Browse files
author
Alex
authored
catching promise - legacy provider error (#7022)
* adding data check for revert util method * fix up tests * fix lint * change legacy request * revert contract changes, add try catch * fix lint * fix changes * update tests * lint and feedback * update test * update test * format
1 parent 0408125 commit 866469d

File tree

5 files changed

+106
-14
lines changed

5 files changed

+106
-14
lines changed

packages/web3-core/src/web3_request_manager.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ export class Web3RequestManager<
210210
) as JsonRpcPayload;
211211

212212
if (!isNullish(this.middleware)) {
213-
payload = (await this.middleware.processRequest(payload));
213+
payload = await this.middleware.processRequest(payload);
214214
}
215215
if (isWeb3Provider(provider)) {
216216
let response;
@@ -248,7 +248,7 @@ export class Web3RequestManager<
248248
// TODO: This could be deprecated and removed.
249249
if (isLegacyRequestProvider(provider)) {
250250
return new Promise<JsonRpcResponse<ResponseType>>((resolve, reject) => {
251-
const rejectWithError = (err: unknown) =>
251+
const rejectWithError = (err: unknown) => {
252252
reject(
253253
this._processJsonRpcResponse(
254254
payload,
@@ -259,6 +259,8 @@ export class Web3RequestManager<
259259
},
260260
),
261261
);
262+
};
263+
262264
const resolveWithResponse = (response: JsonRpcResponse<ResponseType>) =>
263265
resolve(
264266
this._processJsonRpcResponse(payload, response, {
@@ -288,7 +290,20 @@ export class Web3RequestManager<
288290
const responsePromise = result as unknown as Promise<
289291
JsonRpcResponse<ResponseType>
290292
>;
291-
responsePromise.then(resolveWithResponse).catch(rejectWithError);
293+
responsePromise.then(resolveWithResponse).catch(error => {
294+
try {
295+
// Attempt to process the error response
296+
const processedError = this._processJsonRpcResponse(
297+
payload,
298+
error as JsonRpcResponse<ResponseType, unknown>,
299+
{ legacy: true, error: true },
300+
);
301+
reject(processedError);
302+
} catch (processingError) {
303+
// Catch any errors that occur during the error processing
304+
reject(processingError);
305+
}
306+
});
292307
}
293308
});
294309
}

packages/web3-core/test/unit/web3_request_manager.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ describe('Web3RequestManager', () => {
280280
expect(myProvider.request).toHaveBeenCalledTimes(1);
281281
expect(await pr).toBe('test');
282282
});
283+
283284
it('Got a "nullish" response from provider', async () => {
284285
const manager = new Web3RequestManager(undefined, undefined);
285286
const myProvider = {
@@ -1134,6 +1135,38 @@ describe('Web3RequestManager', () => {
11341135
expect(myProvider.request).toHaveBeenCalledWith(payload, expect.any(Function));
11351136
});
11361137

1138+
it('should error in isPromise', async () => {
1139+
const manager = new Web3RequestManager();
1140+
const myProvider = {
1141+
request: jest
1142+
.fn()
1143+
.mockImplementation(async () => Promise.reject(errorResponse)),
1144+
} as any;
1145+
1146+
jest.spyOn(manager, 'provider', 'get').mockReturnValue(myProvider);
1147+
1148+
await expect(manager.sendBatch(request)).rejects.toEqual(errorResponse);
1149+
expect(myProvider.request).toHaveBeenCalledTimes(1);
1150+
expect(myProvider.request).toHaveBeenCalledWith(payload, expect.any(Function));
1151+
});
1152+
1153+
it('should catch error and process json response in isPromise', async () => {
1154+
const manager = new Web3RequestManager();
1155+
const myProvider = {
1156+
request: jest
1157+
.fn()
1158+
.mockImplementation(async () => Promise.reject(errorResponse)),
1159+
} as any;
1160+
jest.spyOn(manager as any, '_processJsonRpcResponse').mockImplementation(() => {
1161+
return errorResponse;
1162+
});
1163+
jest.spyOn(manager, 'provider', 'get').mockReturnValue(myProvider);
1164+
1165+
await expect(manager.sendBatch(request)).rejects.toEqual(errorResponse);
1166+
expect(myProvider.request).toHaveBeenCalledTimes(1);
1167+
expect(myProvider.request).toHaveBeenCalledWith(payload, expect.any(Function));
1168+
});
1169+
11371170
it('should pass request to provider and reject if provider returns error', async () => {
11381171
const manager = new Web3RequestManager();
11391172
const myProvider = {

packages/web3-eth/test/integration/web3_eth/send_transaction.test.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ describe('Web3Eth.sendTransaction', () => {
9090
expect(response.status).toBe(BigInt(1));
9191
expect(response.events).toBeUndefined();
9292

93-
const minedTransactionData = await web3EthWithWallet.getTransaction(response.transactionHash);
93+
const minedTransactionData = await web3EthWithWallet.getTransaction(
94+
response.transactionHash,
95+
);
9496

9597
expect(minedTransactionData).toMatchObject({
9698
from: tempAcc.address,
@@ -119,7 +121,9 @@ describe('Web3Eth.sendTransaction', () => {
119121
expect(response.status).toBe(BigInt(1));
120122
expect(response.events).toBeUndefined();
121123

122-
const minedTransactionData = await web3EthWithWallet.getTransaction(response.transactionHash);
124+
const minedTransactionData = await web3EthWithWallet.getTransaction(
125+
response.transactionHash,
126+
);
123127

124128
expect(minedTransactionData).toMatchObject({
125129
from: tempAcc.address,
@@ -152,7 +156,9 @@ describe('Web3Eth.sendTransaction', () => {
152156
expect(response.status).toBe(BigInt(1));
153157
expect(response.events).toBeUndefined();
154158

155-
const minedTransactionData = await web3EthWithWallet.getTransaction(response.transactionHash);
159+
const minedTransactionData = await web3EthWithWallet.getTransaction(
160+
response.transactionHash,
161+
);
156162

157163
expect(minedTransactionData).toMatchObject({
158164
from: tempAcc.address,
@@ -534,9 +540,12 @@ describe('Web3Eth.sendTransaction', () => {
534540
from: tempAcc.address,
535541
data: SimpleRevertDeploymentData,
536542
};
537-
simpleRevertDeployTransaction.gas = await web3Eth.estimateGas(simpleRevertDeployTransaction);
538-
simpleRevertContractAddress = (await web3Eth.sendTransaction(simpleRevertDeployTransaction))
539-
.contractAddress as Address;
543+
simpleRevertDeployTransaction.gas = await web3Eth.estimateGas(
544+
simpleRevertDeployTransaction,
545+
);
546+
simpleRevertContractAddress = (
547+
await web3Eth.sendTransaction(simpleRevertDeployTransaction)
548+
).contractAddress as Address;
540549
});
541550

542551
it('Should throw TransactionRevertInstructionError because gas too low', async () => {
@@ -578,7 +587,9 @@ describe('Web3Eth.sendTransaction', () => {
578587
const transaction: Transaction = {
579588
from: tempAcc.address,
580589
to: '0x0000000000000000000000000000000000000000',
581-
value: BigInt('99999999999999999999999999999999999999999999999999999999999999999'),
590+
value: BigInt(
591+
'99999999999999999999999999999999999999999999999999999999999999999',
592+
),
582593
};
583594

584595
const expectedThrownError = {
@@ -587,7 +598,9 @@ describe('Web3Eth.sendTransaction', () => {
587598
code: 402,
588599
reason:
589600
getSystemTestBackend() === BACKEND.GETH
590-
? expect.stringContaining('err: insufficient funds for gas * price + value: address')
601+
? expect.stringContaining(
602+
'err: insufficient funds for gas * price + value: address',
603+
)
591604
: 'VM Exception while processing transaction: insufficient balance',
592605
};
593606

packages/web3/test/integration/external-providers/hardhat.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
1818
// eslint-disable-next-line import/no-extraneous-dependencies
1919
import hardhat from 'hardhat';
2020

21-
import { performBasicRpcCalls } from './helper';
21+
import { performBasicRpcCalls, failErrorCalls} from './helper';
2222

2323
describe('compatibility with `hardhat` provider', () => {
2424
it('should initialize Web3, get accounts & block number and send a transaction', async () => {
2525
// use the hardhat provider for web3.js
26-
await performBasicRpcCalls(hardhat.network.provider);
26+
await expect(performBasicRpcCalls(hardhat.network.provider)).resolves.not.toThrow();
2727
});
28+
it('should throw on error calls', async () => {
29+
const result = failErrorCalls(hardhat.network.provider);
30+
await expect(result).rejects.toThrow();
31+
32+
})
2833
});

packages/web3/test/integration/external-providers/helper.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

1818
import { SupportedProviders } from 'web3-types';
19+
import { Contract } from 'web3-eth-contract';
1920
import Web3 from '../../../src/index';
21+
import { BasicAbi, BasicBytecode } from '../../shared_fixtures/build/Basic';
2022

2123
/**
2224
* Performs basic RPC calls (like `eth_accounts`, `eth_blockNumber` and `eth_sendTransaction`)
@@ -36,7 +38,7 @@ export async function performBasicRpcCalls(provider: SupportedProviders) {
3638
to: accounts[1],
3739
from: accounts[0],
3840
value: '1',
39-
gas: 21000
41+
gas: 21000,
4042
});
4143
expect(tx.status).toBe(BigInt(1));
4244

@@ -46,3 +48,27 @@ export async function performBasicRpcCalls(provider: SupportedProviders) {
4648
// After sending a transaction, the blocknumber is supposed to be greater than or equal the block number before sending the transaction
4749
expect(blockNumber1).toBeGreaterThanOrEqual(blockNumber0);
4850
}
51+
52+
export async function failErrorCalls(provider: SupportedProviders) {
53+
let contract: Contract<typeof BasicAbi>;
54+
const web3 = new Web3(provider);
55+
56+
contract = new web3.eth.Contract(BasicAbi, undefined, {
57+
provider,
58+
});
59+
60+
let deployOptions: Record<string, unknown>;
61+
62+
// eslint-disable-next-line prefer-const
63+
deployOptions = {
64+
data: BasicBytecode,
65+
arguments: [10, 'string init value'],
66+
};
67+
const accounts = await web3.eth.getAccounts();
68+
69+
const sendOptions = { from: accounts[0], gas: '1000000' };
70+
71+
contract = await contract.deploy(deployOptions).send(sendOptions);
72+
73+
await contract.methods.reverts().send({ from: accounts[0] });
74+
}

0 commit comments

Comments
 (0)