Skip to content

Handle custom errors from subtensor#79

Merged
thewhaleking merged 9 commits intostagingfrom
feat/thewhaleking/custom-subtensor-error-handling
Oct 7, 2024
Merged

Handle custom errors from subtensor#79
thewhaleking merged 9 commits intostagingfrom
feat/thewhaleking/custom-subtensor-error-handling

Conversation

@thewhaleking
Copy link
Contributor

@thewhaleking thewhaleking commented Sep 17, 2024

Ported from opentensor/bittensor#2305

In addition to catching the typical error messages we receive, we now also catch errors embedded in SubstrateRequestExceptions by catching these exceptions explicitly and parsing the literal dicts out of the args.

E.g. AsyncSubstrateInterface.submit_extrinsic can raise a SubstrateRequestException in two ways:

A.

responses = (
    await self._make_rpc_request(
        [
            self.make_payload(
                "rpc_request",
                "author_submitAndWatchExtrinsic",
                [str(extrinsic.data)],
            )
        ],
        result_handler=result_handler,
    )
)["rpc_request"]
response = next(
    (r for r in responses if "block_hash" in r and "extrinsic_hash" in r),
    None,
)

if not response:
    raise SubstrateRequestException(responses)

which dumps a number of dict-like responses to the SubstrateRequestException's args.

or:

B.

if "result" not in response:
    raise SubstrateRequestException(response.get("error"))

which dumps the error dict to the SubstrateRequestException's args.

We handle this in both cases by parsing the SubstrateRequestException.args:

if isinstance(error_message, Exception):
    # generally gotten through SubstrateRequestException args
    new_error_message = None
    for arg in error_message.args:
        try:
            d = ast.literal_eval(arg)
            if isinstance(d, dict):
                if "error" in d:  # case A
                    new_error_message = d["error"]
                    break
                elif all(x in d for x in ["code", "message", "data"]):  # case B
                    new_error_message = d
                    break
        except ValueError:
            pass
    if new_error_message is None:  # case C
        return_val = " ".join(error_message.args)
        return f"Subtensor returned: {return_val}"
    else:
        error_message = new_error_message

This also allows us to handle the majority of raised SubstrateRequestException args which have a single string with the message included (case C).

@thewhaleking thewhaleking force-pushed the feat/thewhaleking/custom-subtensor-error-handling branch 3 times, most recently from e9492d2 to f17b796 Compare September 25, 2024 09:00
@thewhaleking thewhaleking changed the base branch from main to staging October 4, 2024 16:28
@thewhaleking thewhaleking force-pushed the feat/thewhaleking/custom-subtensor-error-handling branch from f17b796 to 51d94bf Compare October 4, 2024 16:28
@thewhaleking thewhaleking force-pushed the feat/thewhaleking/custom-subtensor-error-handling branch from 3c9b27b to 622261d Compare October 7, 2024 21:06
@thewhaleking thewhaleking merged commit ef94124 into staging Oct 7, 2024
@thewhaleking thewhaleking deleted the feat/thewhaleking/custom-subtensor-error-handling branch October 7, 2024 22:06
@ibraheem-abe ibraheem-abe mentioned this pull request Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants