Skip to content

Commit 41e809f

Browse files
authoredJul 26, 2022
🧢 Decode error string presented in newer versions of hardhat (#763)
1 parent 2e1837c commit 41e809f

File tree

7 files changed

+340
-122
lines changed

7 files changed

+340
-122
lines changed
 

‎.changeset/shy-nails-design.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@ethereum-waffle/chai": patch
3+
"@ethereum-waffle/hardhat": patch
4+
"@ethereum-waffle/provider": patch
5+
---
6+
7+
Decode revert string in hardhat 2.9.4+

‎.github/workflows/CI.yml

+42
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,48 @@ jobs:
2828
run: sudo cp ./.github/workflows/solc /bin
2929
- run: pnpm run build
3030
- run: pnpm run test
31+
test-hardhat-pre-244:
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v2
35+
- name: Use Node.js
36+
uses: actions/setup-node@v1
37+
with:
38+
node-version: 16.x
39+
- run: npm i -g pnpm@7.1.9
40+
- run: pnpm install --frozen-lockfile --strict-peer-dependencies
41+
- name: setup-solc
42+
run: sudo cp ./.github/workflows/solc /bin
43+
- run: pnpm run build
44+
- name: Install versions of hardhat packages pre 2.4.4
45+
run: |
46+
pnpm add hardhat@2.9.2
47+
pnpm add -D @nomiclabs/hardhat-waffle@2.0.3
48+
pnpm add -D @nomiclabs/hardhat-ethers@2.0.3
49+
working-directory: waffle-hardhat
50+
- run: pnpm run test
51+
working-directory: waffle-hardhat
52+
test-hardhat-latest:
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v2
56+
- name: Use Node.js
57+
uses: actions/setup-node@v1
58+
with:
59+
node-version: 16.x
60+
- run: npm i -g pnpm@7.1.9
61+
- run: pnpm install --frozen-lockfile --strict-peer-dependencies
62+
- name: setup-solc
63+
run: sudo cp ./.github/workflows/solc /bin
64+
- run: pnpm run build
65+
- name: Install latest versions of hardhat packages
66+
run: |
67+
pnpm add hardhat@latest
68+
pnpm add -D @nomiclabs/hardhat-waffle@latest
69+
pnpm add -D @nomiclabs/hardhat-ethers@latest
70+
working-directory: waffle-hardhat
71+
- run: pnpm run test
72+
working-directory: waffle-hardhat
3173
docs-and-linter:
3274
runs-on: ubuntu-latest
3375
env:

‎pnpm-lock.yaml

+226-111
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎waffle-chai/src/matchers/revertedWith.ts

+24
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ export function supportRevertedWith(Assertion: Chai.AssertionStatic) {
4343

4444
const decodeHardhatError = (error: any, context: any) => {
4545
const tryDecode = (error: any) => {
46+
if (
47+
error?.errorName &&
48+
/**
49+
* Preserve old behaviour for non-custom errors,
50+
* because if the case of regular errors,
51+
* with revertedWith we match against the argument of error (single string),
52+
* not against the error name like in the case of custom errors - because it is always just Error.
53+
* We don't want to require the user to do `expect(tx).to.be.revertedWith('Error').withArgs('Require cause')`.
54+
*/
55+
error?.errorName !== 'Error' &&
56+
error.errorArgs
57+
) {
58+
context.args = [error.errorArgs];
59+
context.txErrorName = error.errorName;
60+
return error.errorName;
61+
}
4662
const errorString = String(error);
4763
{
4864
const regexp = /VM Exception while processing transaction: reverted with custom error '([a-zA-Z0-9]+)\((.*)\)'/g;
@@ -69,6 +85,14 @@ const decodeHardhatError = (error: any, context: any) => {
6985
return matches[1];
7086
}
7187
}
88+
{
89+
const regexp = new RegExp('reverted with reason string "(.*?)"');
90+
91+
const matches = regexp.exec(errorString);
92+
if (matches && matches.length >= 1) {
93+
return matches[1];
94+
}
95+
}
7296
return undefined;
7397
};
7498

‎waffle-chai/test/matchers/revertedWithTest.ts

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {expect} from 'chai';
2-
import {Wallet, Contract, ContractFactory} from 'ethers';
2+
import {Wallet, Contract, ContractFactory, BigNumber} from 'ethers';
33
import {MATCHERS_ABI, MATCHERS_BYTECODE} from '../contracts/Matchers';
44

55
import type {TestProvider} from '@ethereum-waffle/provider';
@@ -34,7 +34,17 @@ export const revertedWithTest = (provider: TestProvider, options: RevertedWithTe
3434
});
3535

3636
it('Throw: success', async () => {
37-
await expect(matchers.doThrow()).to.be.revertedWith('');
37+
let oneOrTheOtherPassing = false;
38+
// Both are OK, exact output depends on installed version of Hardhat.
39+
try {
40+
await expect(matchers.doThrow()).to.be.revertedWith('');
41+
oneOrTheOtherPassing = !oneOrTheOtherPassing;
42+
} catch {}
43+
try {
44+
await expect(matchers.doThrow()).to.be.revertedWith('Panic');
45+
oneOrTheOtherPassing = !oneOrTheOtherPassing;
46+
} catch (e) {}
47+
expect(oneOrTheOtherPassing).to.be.true;
3848
});
3949

4050
it('Throw: fail when message is expected', async () => {
@@ -164,9 +174,19 @@ export const revertedWithTest = (provider: TestProvider, options: RevertedWithTe
164174
});
165175

166176
it('Not to revert: fail', async () => {
167-
await expect(
168-
expect(matchers.doThrow()).not.to.be.revertedWith('')
169-
).to.be.eventually.rejected;
177+
let oneOrTheOtherRejected = false;
178+
// Both are OK, exact output depends on installed version of Hardhat.
179+
try {
180+
await expect(matchers.doThrow()).not.to.be.revertedWith('');
181+
} catch {
182+
oneOrTheOtherRejected = !oneOrTheOtherRejected;
183+
}
184+
try {
185+
await expect(matchers.doThrow()).not.to.be.revertedWith('Panic');
186+
} catch {
187+
oneOrTheOtherRejected = !oneOrTheOtherRejected;
188+
}
189+
expect(oneOrTheOtherRejected).to.be.true;
170190
});
171191

172192
it('Revert: fail when same message was thrown', async () => {
@@ -189,7 +209,17 @@ export const revertedWithTest = (provider: TestProvider, options: RevertedWithTe
189209

190210
if (panicCodes) {
191211
it('Handle panic error', async () => {
192-
await expect(matchers.doPanic()).to.be.revertedWith('panic code 0x12');
212+
let oneOrTheOtherPassing = false;
213+
// Both are OK, exact output depends on installed version of Hardhat.
214+
try {
215+
await expect(matchers.doPanic()).to.be.revertedWith('panic code 0x12');
216+
oneOrTheOtherPassing = !oneOrTheOtherPassing;
217+
} catch {}
218+
try {
219+
await expect(matchers.doPanic()).to.be.revertedWith('Panic').withArgs(BigNumber.from('0x12'));
220+
oneOrTheOtherPassing = !oneOrTheOtherPassing;
221+
} catch (e) {}
222+
expect(oneOrTheOtherPassing).to.be.true;
193223
});
194224
}
195225
};

‎waffle-hardhat/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
},
2121
"dependencies": {
2222
"ethers": "5.6.2",
23-
"hardhat": "^2.9.2"
23+
"hardhat": "2.10.1"
2424
},
2525
"devDependencies": {
2626
"@ethereum-waffle/chai": "workspace:*",
27-
"@nomiclabs/hardhat-ethers": "^2.0.3",
28-
"@nomiclabs/hardhat-waffle": "^2.0.3",
27+
"@nomiclabs/hardhat-ethers": "2.1.0",
28+
"@nomiclabs/hardhat-waffle": "2.0.3",
2929
"@types/node": "^17.0.41",
3030
"eslint": "^7.14.0",
3131
"ethereum-waffle": "workspace:*",

‎waffle-hardhat/test/reverted.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('INTEGRATION: Matchers: revertedWith', () => {
6969
'message',
7070
'0x00cfbbaf7ddb3a1476767101c12a0162e241fbad2a0162e2410cfbbaf7162123'
7171
)
72-
).to.be.eventually.rejectedWith('expected 0 to equal 1');
72+
).to.be.eventually.rejectedWith(/Expected (")?0(")? to (be )?equal 1/i); // It may or may not have the quote marks
7373
await expect(expect(matchers.doRevertWithOne())
7474
.to.be.revertedWith('One')
7575
.withArgs(
@@ -116,7 +116,7 @@ describe('INTEGRATION: Matchers: revertedWith', () => {
116116
'0x00cfbbaf7ddb3a1476767101c12a0162e241fbad2a0162e2410cfbbaf7162124'
117117
]
118118
)
119-
).to.be.eventually.rejectedWith('expected 3 to equal 4');
119+
).to.be.eventually.rejectedWith(/Expected (")?3(")? to (be )?equal 4/i); // It may or may not have the quote marks
120120
await expect(expect(matchers.doRevertWithTwo())
121121
.to.be.revertedWith('Two')
122122
.withArgs(

0 commit comments

Comments
 (0)
Please sign in to comment.