customError.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. const { expect } = require('chai');
  2. /** Revert handler that supports custom errors. */
  3. async function expectRevertCustomError(promise, expectedErrorName, args) {
  4. if (!Array.isArray(args)) {
  5. expect.fail('Expected 3rd array parameter for error arguments');
  6. }
  7. await promise.then(
  8. () => expect.fail("Expected promise to throw but it didn't"),
  9. ({ message }) => {
  10. // The revert message for custom errors looks like:
  11. // VM Exception while processing transaction:
  12. // reverted with custom error 'InvalidAccountNonce("0x70997970C51812dc3A010C7d01b50e0d17dc79C8", 0)'
  13. // Attempt to parse as a custom error
  14. const match = message.match(/custom error '(?<name>\w+)\((?<args>.*)\)'/);
  15. if (!match) {
  16. expect.fail(`Could not parse as custom error. ${message}`);
  17. }
  18. // Extract the error name and parameters
  19. const errorName = match.groups.name;
  20. const argMatches = [...match.groups.args.matchAll(/-?\w+/g)];
  21. // Assert error name
  22. expect(errorName).to.be.equal(
  23. expectedErrorName,
  24. `Unexpected custom error name (with found args: [${argMatches.map(([a]) => a)}])`,
  25. );
  26. // Coerce to string for comparison since `arg` can be either a number or hex.
  27. const sanitizedExpected = args.map(arg => arg.toString().toLowerCase());
  28. const sanitizedActual = argMatches.map(([arg]) => arg.toString().toLowerCase());
  29. // Assert argument equality
  30. expect(sanitizedActual).to.have.members(sanitizedExpected, `Unexpected ${errorName} arguments`);
  31. },
  32. );
  33. }
  34. module.exports = {
  35. expectRevertCustomError,
  36. };