Skip to content

Commit

Permalink
Merge pull request #135 from miohtama/feat/better-abi-errors
Browse files Browse the repository at this point in the history
When ABI call output decoding fails, give more information what happened
  • Loading branch information
pipermerriam committed Dec 28, 2016
2 parents d05604c + 517c59f commit e0778d0
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 1 deletion.
24 changes: 23 additions & 1 deletion web3/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@
)
from eth_abi.exceptions import (
EncodingError,
DecodingError,
)

from web3.exceptions import (
BadFunctionCallOutput,
)

from web3.utils.encoding import (
encode_hex,
)
from web3.utils.exception import (
raise_from,
)
from web3.utils.formatting import (
add_0x_prefix,
remove_0x_prefix,
Expand Down Expand Up @@ -653,7 +661,21 @@ def call_contract_function(contract,
function_abi = contract._find_matching_fn_abi(function_name, args, kwargs)

output_types = get_abi_output_types(function_abi)
output_data = decode_abi(output_types, return_data)

try:
output_data = decode_abi(output_types, return_data)
except DecodingError as e:
# Provide a more helpful error message than the one provided by
# eth-abi-utils
msg = (
"Could not decode contract function call {} return data {} for "
"output_types {}".format(
function_name,
return_data,
output_types
)
)
raise_from(BadFunctionCallOutput(msg), e)

normalized_data = [
normalize_return_type(data_type, data_value)
Expand Down
7 changes: 7 additions & 0 deletions web3/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ def __init__(self, result):
else:
message = "Invalid JSON RPC response: " + json.dumps(result)
Exception.__init__(self, message)


class BadFunctionCallOutput(Exception):
"""We failed to decode ABI output.
Most likely ABI mismatch.
"""
7 changes: 7 additions & 0 deletions web3/utils/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import sys

# raise MyException() from original_exception compatibility
if sys.version_info.major == 2:
from .exception_py2 import raise_from # noqa: F401
else:
from .exception_py3 import raise_from # noqa: F401
2 changes: 2 additions & 0 deletions web3/utils/exception_py2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def raise_from(my_exception, other_exception):
raise my_exception, None, sys.exc_info()[2] # noqa: W602, E999
2 changes: 2 additions & 0 deletions web3/utils/exception_py3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def raise_from(my_exception, other_exception):
raise my_exception from other_exception

0 comments on commit e0778d0

Please sign in to comment.