Storing and printing an exception with traceback?

Question:

In a python3 program I have a certain try...except block where I store exceptions that occur in a certain method into a list of exceptions that have occurred. A simplified version looks like this:

def the_method(iterable):
   errors = []
   for i in iterable:
       try:
           something(i)
        except Exception as e:
            errors.append(e)
   return errors

After the method returns I want to print the errors in the console. How can I print the exceptions with traceback and the usual uncaught exception formatting?

Asked By: OdraEncoded

||

Answers:

Is it work with print command, like

def the_method(iterable):
   errors = []
   for i in iterable:
       try:
           something(i)
        except Exception as e:
            errors.append(e)
   return errors

err = the_method(iterable)
for e in err:
    print e()
Answered By: Hardy

Exceptions have attributes, just like other objects in Python. You may want to explore the attributes of your exceptions. Consider the following example:

>>> try:
    import some_junk_that_doesnt_exist
except Exception as error:
    print(dir(error))


['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', '_not_found', 'args', 'msg', 'name', 'path', 'with_traceback']

This means that for each exception in your list, you can access the exception’s attribute. Thus, you can do the following:

for e in err:
    print(e.args)
    print(e.name)
    print(e.msg)

One thing that occurs to me, though, is that the following line shouldn’t really append more than one exception to your errors list:

except Exception as e:
     errors.append(e)

Someone else will know better than I would, but isn’t Exception always going to be one thing here (unless you’re capturing multiple specific exceptions)?

Answered By: erewok

Use the traceback module. Note that the interface is ancient, so it doesn’t know to use type(exc) and exc.__traceback__; you’ll have to extract those yourself:

for exc in errors:
    traceback.print_exception(type(exc), exc, exc.__traceback__)

Also, be aware that Python has a very strange way of building tracebacks, where an entry for a stack frame is added to the traceback when an exception propagates into that stack frame, rather than building the traceback all at once when the exception is created or raised.

This means that an exception’s traceback stops at the point where it stopped propagating. When your the_method catches an exception, the exception’s traceback will stop at the_method.

Answered By: user2357112
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.