Skip to content

Commit 9d9b14b

Browse files
committedMar 25, 2022
More robust JSON-RPC error handling for reverted executions (#2603).

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed
 

‎packages/providers/src.ts/json-rpc-provider.ts

+33-5
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,48 @@ import { BaseProvider, Event } from "./base-provider";
2222

2323
const errorGas = [ "call", "estimateGas" ];
2424

25+
function spelunk(value: any): null | { message: string, data: string } {
26+
if (value == null) { return null; }
27+
28+
// These *are* the droids we're looking for.
29+
if (typeof(value.message) === "string" && value.message.match("reverted") && isHexString(value.data)) {
30+
return { message: value.message, data: value.data };
31+
}
32+
33+
// Spelunk further...
34+
if (typeof(value) === "object") {
35+
for (const key in value) {
36+
const result = spelunk(value[key]);
37+
if (result) { return result; }
38+
}
39+
return null;
40+
}
41+
42+
// Might be a JSON string we can further descend...
43+
if (typeof(value) === "string") {
44+
try {
45+
return spelunk(JSON.parse(value));
46+
} catch (error) { }
47+
}
48+
49+
return null;
50+
}
51+
2552
function checkError(method: string, error: any, params: any): any {
53+
2654
// Undo the "convenience" some nodes are attempting to prevent backwards
2755
// incompatibility; maybe for v6 consider forwarding reverts as errors
28-
if (method === "call" && error.code === Logger.errors.SERVER_ERROR) {
29-
const e = error.error;
30-
if (e && e.message.match("reverted") && isHexString(e.data)) {
31-
return e.data;
32-
}
56+
if (method === "call") {
57+
const result = spelunk(error);
58+
if (result) { return result.data; }
3359

3460
logger.throwError("missing revert data in call exception", Logger.errors.CALL_EXCEPTION, {
3561
error, data: "0x"
3662
});
3763
}
3864

65+
// @TODO: Should we spelunk for message too?
66+
3967
let message = error.message;
4068
if (error.code === Logger.errors.SERVER_ERROR && error.error && typeof(error.error.message) === "string") {
4169
message = error.error.message;

0 commit comments

Comments
 (0)
Please sign in to comment.