@0x/dev-utils: Move Error -> RevertError coercion logic to @0x/utils.

This commit is contained in:
Lawrence Forman 2019-05-18 02:07:36 -04:00 committed by Amir Bandeali
parent 409efb8c67
commit 882dd4597e
2 changed files with 6 additions and 65 deletions

View File

@ -5,6 +5,10 @@
{
"note": "Add `chaiSetup` function with `RevertError` testing support",
"pr": 1761
},
{
"note": "Refactor out `Error` coercion code into the `utils` package",
"pr": 1819
}
]
},

View File

@ -1,4 +1,4 @@
import { AnyRevertError, RevertError, StringRevertError } from '@0x/utils';
import { coerceThrownErrorAsRevertError, RevertError, StringRevertError } from '@0x/utils';
// tslint:disable only-arrow-functions prefer-conditional-expression
@ -28,18 +28,6 @@ type ChaiAssert = (
actual?: any,
) => void;
interface GanacheTransactionRevertResult {
error: 'revert';
program_counter: number;
return?: string;
reason?: string;
}
interface GanacheTransactionRevertError extends Error {
results: { [hash: string]: GanacheTransactionRevertResult };
hashes: string[];
}
export function revertErrorHelper(_chai: Chai): void {
const proto = _chai.Assertion;
proto.overwriteMethod('revertWith', function(_super: ChaiPromiseHandler): ChaiPromiseHandler {
@ -111,7 +99,7 @@ function compareRevertErrors(
if (typeof actual === 'string') {
actual = new StringRevertError(actual);
} else if (actual instanceof Error) {
actual = coerceErrorToRevertError(actual);
actual = coerceThrownErrorAsRevertError(actual);
} else {
chaiAssert(_chai, false, `Result is not of type RevertError: ${actual}`);
}
@ -136,57 +124,6 @@ function compareRevertErrors(
return false;
}
const GANACHE_TRANSACTION_REVERT_ERROR_MESSAGE = /^VM Exception while processing transaction: revert/;
const GETH_TRANSACTION_REVERT_ERROR_MESSAGE = /always failing transaction$/;
function coerceErrorToRevertError(error: Error | GanacheTransactionRevertError): RevertError {
// Handle ganache transaction reverts.
if (isGanacheTransactionRevertError(error)) {
// Grab the first result attached.
const result = error.results[error.hashes[0]];
// If a reason is provided, just wrap it in a StringRevertError
if (result.reason !== undefined) {
return new StringRevertError(result.reason);
}
// If there is return data, try to decode it.
if (result.return !== undefined && result.return !== '0x') {
return RevertError.decode(result.return);
}
// Otherwise, return an AnyRevertError type.
return new AnyRevertError();
}
// Handle geth transaction reverts.
if (isGethTransactionRevertError(error)) {
// Geth transaction reverts are opaque, meaning no useful data is returned,
// so we just return an AnyRevertError type.
return new AnyRevertError();
}
// Handle call reverts.
// `BaseContract` will throw a plain `Error` type for `StringRevertErrors`
// in callAsync functions for backwards compatibility, and a proper RevertError
// for all others.
if (error instanceof RevertError) {
return error;
}
// Coerce plain errors into a StringRevertError.
return new StringRevertError(error.message);
}
function isGanacheTransactionRevertError(
error: Error | GanacheTransactionRevertError,
): error is GanacheTransactionRevertError {
if (GANACHE_TRANSACTION_REVERT_ERROR_MESSAGE.test(error.message) && 'hashes' in error && 'results' in error) {
return true;
}
return false;
}
function isGethTransactionRevertError(error: Error | GanacheTransactionRevertError): boolean {
return GETH_TRANSACTION_REVERT_ERROR_MESSAGE.test(error.message);
}
function chaiAssert(_chai: Chai, condition: boolean, failMessage?: string, expected?: any, actual?: any): void {
const assert = new _chai.Assertion();
assert.assert(condition, failMessage, undefined, expected, actual);