diff --git a/algosdk/error.py b/algosdk/error.py index b0931977..299a4b24 100644 --- a/algosdk/error.py +++ b/algosdk/error.py @@ -178,9 +178,10 @@ def __init__(self, msg): class AlgodHTTPError(Exception): - def __init__(self, msg, code=None): + def __init__(self, msg, code=None, data=None): super().__init__(msg) self.code = code + self.data = data class AlgodResponseError(Exception): diff --git a/algosdk/v2client/algod.py b/algosdk/v2client/algod.py index bd2f4189..eae2047c 100644 --- a/algosdk/v2client/algod.py +++ b/algosdk/v2client/algod.py @@ -105,10 +105,13 @@ def algod_request( except urllib.error.HTTPError as e: code = e.code es = e.read().decode("utf-8") + m = e # If json.loads() fails, we'll return e itself + j = {} try: - e = json.loads(es)["message"] + j = json.loads(es) + m = j["message"] finally: - raise error.AlgodHTTPError(e, code) + raise error.AlgodHTTPError(m, code, j.get("data")) if response_format == "json": try: return json.load(resp) diff --git a/examples/inspect-error.py b/examples/inspect-error.py new file mode 100755 index 00000000..427db724 --- /dev/null +++ b/examples/inspect-error.py @@ -0,0 +1,20 @@ +from algosdk import error, transaction + +from utils import get_algod_client, algod_env + +algod = get_algod_client(*algod_env()) + +# This program is "#pragma version 5, +". It will fail because no arguments are on the stack. +lsig = transaction.LogicSigAccount(b"\x05\x08") +sender = lsig.address() +# Get suggested parameters +params = algod.suggested_params() + +amount = 10000 +txn = transaction.PaymentTxn(sender, params, sender, amount) +lstx = transaction.LogicSigTransaction(txn, lsig) +try: + txid = algod.send_transaction(lstx) + print("Impossible! Exception will have been thrown") +except error.AlgodHTTPError as e: + print(e.data) diff --git a/examples/utils.py b/examples/utils.py index 64c3958d..59e84019 100644 --- a/examples/utils.py +++ b/examples/utils.py @@ -67,6 +67,23 @@ class SandboxAccount: signer: AccountTransactionSigner +def algod_env(): + algodata = os.environ.get("ALGORAND_DATA") + if not algodata: + return () + try: + token = ( + open(os.path.join(algodata, "algod.token"), "rt").read().strip() + ) + net = ( + "http://" + + open(os.path.join(algodata, "algod.net"), "rt").read().strip() + ) + return (net, token) + except FileNotFoundError: + return () + + def get_accounts( kmd_address: str = KMD_URL, kmd_token: str = KMD_TOKEN,