RevertError: Decode Parity revert errors

This commit is contained in:
Jacob Evans 2019-11-15 19:07:28 +10:00
parent 58276cefce
commit 42dc112a13
No known key found for this signature in database
GPG Key ID: 2036DA2ADDFB0842
3 changed files with 45 additions and 2 deletions

View File

@ -5,6 +5,10 @@
{
"note": "Removed exports AuthorizableRevertErrors, LibAddressArrayRevertErrors, LibBytesRevertErrors, OwnableRevertErrors, ReentrancyGuardRevertErrors and SafeMathRevertErrors",
"pr": 2321
},
{
"note": "Decode `Parity` revert errors",
"pr": 2341
}
]
},

View File

@ -314,6 +314,7 @@ export abstract class RevertError extends Error {
}
}
const PARITY_TRANSACTION_REVERT_ERROR_MESSAGE = /^VM execution error/;
const GANACHE_TRANSACTION_REVERT_ERROR_MESSAGE = /^VM Exception while processing transaction: revert/;
const GETH_TRANSACTION_REVERT_ERROR_MESSAGE = /always failing transaction$/;
@ -329,10 +330,18 @@ interface GanacheTransactionRevertError extends Error {
hashes: string[];
}
interface ParityTransactionRevertError extends Error {
code: number;
data: string;
message: string;
}
/**
* Try to extract the ecnoded revert error bytes from a thrown `Error`.
*/
export function getThrownErrorRevertErrorBytes(error: Error | GanacheTransactionRevertError): string {
export function getThrownErrorRevertErrorBytes(
error: Error | GanacheTransactionRevertError | ParityTransactionRevertError,
): string {
// Handle ganache transaction reverts.
if (isGanacheTransactionRevertError(error)) {
// Grab the first result attached.
@ -344,6 +353,13 @@ export function getThrownErrorRevertErrorBytes(error: Error | GanacheTransaction
if (result.return !== undefined && result.return !== '0x') {
return result.return;
}
} else if (isParityTransactionRevertError(error)) {
// Parity returns { data: 'Reverted 0xa6bcde47...', ... }
const { data } = error;
const hexDataIndex = data.indexOf('0x');
if (hexDataIndex !== -1) {
return data.slice(hexDataIndex);
}
} else {
// Handle geth transaction reverts.
if (isGethTransactionRevertError(error)) {
@ -354,6 +370,15 @@ export function getThrownErrorRevertErrorBytes(error: Error | GanacheTransaction
throw new Error(`Cannot decode thrown Error "${error.message}" as a RevertError`);
}
function isParityTransactionRevertError(
error: Error | ParityTransactionRevertError,
): error is ParityTransactionRevertError {
if (PARITY_TRANSACTION_REVERT_ERROR_MESSAGE.test(error.message) && 'code' in error && 'data' in error) {
return true;
}
return false;
}
function isGanacheTransactionRevertError(
error: Error | GanacheTransactionRevertError,
): error is GanacheTransactionRevertError {

View File

@ -1,7 +1,13 @@
import * as chai from 'chai';
import * as _ from 'lodash';
import { AnyRevertError, RawRevertError, RevertError, StringRevertError } from '../src/revert_error';
import {
AnyRevertError,
getThrownErrorRevertErrorBytes,
RawRevertError,
RevertError,
StringRevertError,
} from '../src/revert_error';
import { chaiSetup } from './utils/chai_setup';
@ -154,6 +160,14 @@ describe('RevertError', () => {
expect(decode).to.throw();
});
});
describe('getThrownErrorRevertErrorBytes', () => {
it('should decode Parity revert errors', () => {
const revertAbi = '0x1234';
const parityError = { code: 1234, message: 'VM execution error.', data: `Reverted ${revertAbi}`, name: '' };
const revertError = getThrownErrorRevertErrorBytes(parityError);
expect(revertError).to.be.eq(revertAbi);
});
});
describe('encoding', () => {
const message = 'foobar';
it('should be able to encode', () => {