Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In python 3, re-raise an error with a shorter traceback

I'm trying to create a try-except block that re-raises an arbitrary exception, but only includes the final block in the traceback stack.

Something like this:

import traceback

def my_func(shorten_tracebacks=True):
    try:
        # Do stuff here

    except Exception as e:
        if shorten_tracebacks:
            raise TheSameTypeOfError, e, traceback.print_exc(limit=1)

        else:
            raise(e)

Is there a preferred way to do this?

In case it matters, I'm doing this for convenience in debugging certain APIs that are often used in jupyter notebooks---they tend to generate really long stack traces where only the last block is informative. This forces the user to scroll a lot. If you don't want to shorten the traceback, you can always set shorten_tracebacks=False

like image 743
Abe Avatar asked Nov 07 '22 04:11

Abe


1 Answers

My preference is to create a new exception without a context (if an exception has a context python will print both the exception and the exception which caused that exception, and the exception which caused that exception, and so on...)

try:
    ...
except:
    raise Exception("Can't ramistat the foo, is foo installed?") from None

Some best practices:

  • Include relevant debugging information in the exception message.
  • Use a custom exception type, so callers can catch the new exception.
  • Catch only the specific error types you're expecting, to let unexpected errors fall through with the extended traceback.

The downside to this approach is that if your exception catching is overly broad, you can end up suppressing useful context which is important to debugging the exception. An alternate pattern might look like this:

try:
    ...
except Exception as e:
    if "ramistat not found" in e.message:
        # The ramistat is missing. This is a common kind of error.
        # Create a more helpful and shorter message
        raise Exception("Can't ramistat the foo, is foo installed?") from None
    else:
        # Some other kind of problem
        raise e

Essentially, you check the exception, and replace it with a custom message if it's a kind of error you know how to deal with. Otherwise, you re-raise the original exception, and let the user figure out what to do.

like image 53
Nick ODell Avatar answered Nov 15 '22 10:11

Nick ODell