0👍
The good practice is to raise your own exception (here it is APIException
) and attach the original exception.
You can take a look at six.raise_from (if you want a Python 2/3 compatible solution):
Raise an exception from a context. On Python 3, this is equivalent to
raise exc_value from exc_value_from
. On Python 2, which does not support exception chaining, it is equivalent to raise exc_value.
You can also create your own exception class which can do the chaining.
class APIException(Exception):
def __init__(self, msg, exc_from=None):
self.exc_from = exc_from
if exc_from:
msg += ': raise from {0}'.format(str(exc_from))
super(APIException, self).__init__(self, msg)
# demo
def do_stuff():
raise KeyError('bad key')
def main():
try:
do_stuff()
except KeyError as exc:
raise APIException('error in main', exc)
try:
main()
except APIException as exc:
print(str(exc))
Of course, instead of printing/logging your APIException error message you can log your original message:
try:
main()
except APIException as exc:
print(str(exc.exc_from))
Edit: Use class hierarchy for exceptions
But, if do_stuff()
is part of your API, it’s a better practice to do the exception handling inside this function and throw your own exception which can inherit APIException
.
class APIException(Exception):
pass
class BadStuffError(APIException):
pass
def do_stuff():
try:
# ...
raise KeyError('bad key')
except KeyError as exc:
raise BadStuffError('bad stuff: ' + exc.args[0])
def main():
do_stuff()
try:
main()
except APIException as exc:
print(str(exc))
This solution is the best, IMO.
0👍
Since you are using Python 3, you can simply raise the APIException
:
try:
do_stuff()
except KeyError as exc:
raise APIException() from exc
Then in your exception handler, if exc
is the APIException
, you can access the original exception with exc.__context__
.
def exception_handler(exc):
logger.log(exc.__context__)
return Response({"message": "try again sam"}, status_code=400)
The from exc
is not actually needed to be able to access __context__
, but it makes it clear that the KeyError
was converted to APIException
, rather than APIException
being raised during the handling of KeyError
.
See the exception docs for more info.
- [Django]-Django middleware to determine user's group in a session
- [Django]-Django Multiple Levels Choices for Field