Skip to content

Commit 58f52fc

Browse files
committed
Catch if data is None in revert error
1 parent 4b509a7 commit 58f52fc

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

newsfragments/3054.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Handle case where data gets returned as ``None`` in a JSON-RPC error response

tests/core/utilities/test_method_formatters.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,42 @@
101101
}
102102
)
103103

104+
NONE_DATA_RESPONSE = RPCResponse(
105+
{
106+
"id": 24,
107+
"jsonrpc": "2.0",
108+
"error": {
109+
"message": "execution reverted",
110+
"code": -32000,
111+
"data": None,
112+
},
113+
}
114+
)
115+
116+
NONE_MESSAGE_RESPONSE = RPCResponse(
117+
{
118+
"id": 24,
119+
"jsonrpc": "2.0",
120+
"error": {
121+
"message": None,
122+
"code": -32000,
123+
"data": "execution reverted", # noqa: E501
124+
},
125+
}
126+
)
127+
128+
NO_DATA_NO_MESSAGE_RESPONSE = RPCResponse(
129+
{
130+
"id": 24,
131+
"jsonrpc": "2.0",
132+
"error": {
133+
"message": None,
134+
"code": -32000,
135+
"data": None, # noqa: E501
136+
},
137+
}
138+
)
139+
104140

105141
@pytest.mark.parametrize(
106142
"response,expected",
@@ -116,13 +152,28 @@
116152
SPACENETH_RESPONSE,
117153
"execution reverted: OwnerId does not exist in registry",
118154
),
155+
(
156+
NONE_DATA_RESPONSE,
157+
"execution reverted",
158+
),
159+
(
160+
NONE_MESSAGE_RESPONSE,
161+
"execution reverted",
162+
),
163+
(
164+
NO_DATA_NO_MESSAGE_RESPONSE,
165+
"execution reverted",
166+
),
119167
),
120168
ids=[
121169
"test-get-revert-reason-with-msg",
122170
"test-get-revert-reason-without-msg",
123171
"test-get-geth-revert-reason",
124172
"test_get-ganache-revert-reason",
125173
"test_get-spaceneth-revert-reason",
174+
"test_none-data-response",
175+
"test_none-message-response",
176+
"test_no-data-no-message-response",
126177
],
127178
)
128179
def test_get_revert_reason(response, expected) -> None:

web3/_utils/contract_error_handling.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,21 @@ def raise_contract_logic_error_on_revert(response: RPCResponse) -> RPCResponse:
6565
raise ValueError("Error expected to be a dict")
6666

6767
data = response["error"].get("data", "")
68+
message = response["error"].get("message", "")
69+
70+
message_present = message is not None and message != ""
71+
72+
if data is None:
73+
if message_present:
74+
raise ContractLogicError(message)
75+
elif not message_present:
76+
raise ContractLogicError("execution reverted")
77+
else:
78+
raise Exception("Unreachable")
6879

6980
# Ganache case:
70-
if isinstance(data, dict) and response["error"].get("message"):
71-
raise ContractLogicError(
72-
f'execution reverted: {response["error"]["message"]}', data=data
73-
)
81+
if isinstance(data, dict) and message_present:
82+
raise ContractLogicError(f"execution reverted: {message}", data=data)
7483

7584
# Parity/OpenEthereum case:
7685
if data.startswith("Reverted "):
@@ -126,12 +135,10 @@ def raise_contract_logic_error_on_revert(response: RPCResponse) -> RPCResponse:
126135
raise ContractCustomError(data, data=data)
127136

128137
# Geth case:
129-
if "message" in response["error"] and response["error"].get("code", "") == 3:
130-
message = response["error"]["message"]
138+
if message_present and response["error"].get("code", "") == 3:
131139
raise ContractLogicError(message, data=data)
132-
133140
# Geth Revert without error message case:
134-
if "execution reverted" in response["error"].get("message"):
141+
if message_present and "execution reverted" in message:
135142
raise ContractLogicError("execution reverted", data=data)
136143

137144
return response

0 commit comments

Comments
 (0)