Reputation: 81
So suppose I have some code that raises any type or error. I want my code instead to raise an AssertionError, but print out the original message of that would have been printed with the original error. How would I do that?
(example)
original error: TypeError: '>' not supported between instances of 'str' and 'int'
custom error: AssertionError: exception = TypeError: '>' not supported between instances of 'str' and 'int'
Upvotes: 3
Views: 688
Reputation: 20450
You are looking for the from
syntax (introduced in Python 3) that lets you wrap an app-specific exception around a base exception.
Here is an example:
>>> try:
... 1 > '1'
... except TypeError as e:
... raise AssertionError() from e
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: '>' not supported between instances of 'int' and 'str'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
AssertionError
You can supply a string containing a diagnostic message when you create a new exception. It would be better to define your own app-specific exception(s), rather than recycling AssertionError. If you define several, make one of them the [grand]parent and have other exceptions inherit from that ancestor. That allows callers to conveniently catch fine- or coarse-grained classes of errors.
There's a PEP that describes further considerations.
Upvotes: 3
Reputation: 8520
Also you can hide original traceback by setting __suppress_context__ = True
and make some formatting to fit your needs of expected output:
try:
a = '1' > 1
except Exception as exc:
assertion_exc = AssertionError('exception = {}: {}'.format(type(exc).__name__, str(exc)))
assertion_exc.__suppress_context__ = True # comment this line to see full traceback
raise assertion_exc
Full output:
Traceback (most recent call last):
File "./file.py", line 8, in <module>
raise assertion_exc
AssertionError: exception = TypeError: '>' not supported between instances of 'str' and 'int'
Upvotes: 1
Reputation: 906
You'll have to catch the exception raised and then raise whichever type you'd like. Since you mentioned wanting to catch any type of error you would have to use the Exception
class as your catch.
However, I would note that this is generally bad practice because you typically want to only catch specific errors that you anticipate having. But if you end up throwing an error anyways, i suppose its not terrible. But also make me wonder specifically what the goal of this code is. Anyways..
catch anything
try...except Exception as e
raise preferred error
raise AssertionError()
get the message
e.message
get the type
type(e)
Putting it all together:
try:
# some code that raises an error
g = 10 + '11'
except Exception as e:
raise AssertionError('{}: {}'.format(type(e), e.message))
The output would be:
<type 'exceptions.TypeError'>: unsupported operand type(s) for +: 'int' and 'str'
This could be cleaned up to get rid of the ugly output of the type(e)
but in general this is how you would include the type of error as well as its corresponding message.
Upvotes: 3