In some cases, I need to raise my exception because built-in exceptions are not fit to my programs. After I defined my exception, python raises both my exception and built-in exception, how to handle this situation? I want to only print mine?
class MyExceptions(ValueError):
"""Custom exception."""
pass
try:
int(age)
except ValueError:
raise MyExceptions('age should be an integer, not str.')
The output:
Traceback (most recent call last):
File "new.py", line 10, in <module>
int(age)
ValueError: invalid literal for int() with base 10: 'merry_christmas'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "new.py", line 12, in <module>
raise MyExceptions('age should be an integer, not str.')
__main__.MyExceptions: age should be an integer, not str.
I want to print something like this:
Traceback (most recent call last):
File "new.py", line 10, in <module>
int(age)
MyException: invalid literal for int() with base 10: 'merry_christmas'
Answer
In Python, when you raise a custom exception inside an except
block that is already handling a built-in exception, the new exception is raised on top of the original one, which is why you are seeing both the built-in ValueError
and your custom MyExceptions
. However, you can suppress the built-in exception and only raise and print your custom exception by using the raise ... from None
construct.
The raise ... from None
syntax is used to suppress the context of the original exception and only show the custom exception.
Here’s how you can modify your code to achieve the desired behavior:
class MyExceptions(ValueError):
"""Custom exception."""
pass
try:
age = 'merry_christmas' # example input that will fail
int(age)
except ValueError as e:
raise MyExceptions(f"age should be an integer, not str. Original error: {e}") from None
Explanation:
-
raise MyExceptions(...) from None
: Thefrom None
part ensures that the traceback of the originalValueError
is suppressed, and only the customMyExceptions
exception is shown in the output. -
Custom error message: You can still include the original error message (in this case, the
ValueError
message) in the custom exception message if you need it.
Expected Output:
Traceback (most recent call last):
File "new.py", line 10, in <module>
int(age)
MyExceptions: age should be an integer, not str. Original error: invalid literal for int() with base 10: 'merry_christmas'
This approach ensures that only your custom exception message is displayed, and the traceback is cleaner and more focused on your custom exception.