[Dev] Python exception handling (was Re: Dabo, Wax, others?)

Phillip J. Eby pje at telecommunity.com
Fri Sep 16 10:35:45 PDT 2005


At 10:22 AM 9/16/2005 -0700, Alec Flett wrote:
>In our case, I think heikki is saying that for end users, if we get an 
>exception at the top level, where developers would normally see a dialog 
>box with all sorts of ugly code, end-users should see a user-friendly 
>error message recommending the user quits & restarts chandler. Someday it 
>would be nice if the stack trace were sent back to OSAF to be combined 
>with others so we could see a "top exception" report and fix such errors.
>
>Obviously, developers want the actual stack trace  of the exception (an 
>assert being just one kind of exception) and the exception would NOT be 
>sent to a central talkback server, since developers are constantly 
>throwing exceptions during day-to-day debugging :)

Just as a side note, I've occasionally seen Chandler code that formats or 
displays exception data, but does so from the start of the traceback 
instead of the end.  The start of the traceback info isn't helpful, since 
it's going to be the same for all users.

I've also seen code that formats one exception and then re-raises it, which 
destroys debugging information.  In general, the best policy regarding 
exceptions is not to catch them unless your code is actually handling the 
exception.  Let them bubble up to a top-level exception handler in the 
application or in the testing framework.  For example, consider this 
snippet in TestLaunchChandler:

             try:
                 Chandler.main()
                 didLaunch = True

             # Catch exceptions that come all the way out, e.g. parcel.xml 
issues.
             except Exception, exception:
                 type, value, stack = sys.exc_info()
                 formattedBacktrace = "".join (traceback.format_exception 
(type, value, stack, 5))
                 message = ("Chandler encountered an unexpected problem 
which caused this unit test to fail.\n" + \
                           "Here are the bottom 5 frames of the 
stack:\n%s") % formattedBacktrace


This extra code doesn't do anything useful, because the unittest module 
will already format the traceback if an uncaught exception is raised.  It 
could be rewritten as:

                 Chandler.main()

and it would have the same effect, except you wouldn't be limited to 5 
lines of formatting, and if you're using a test runner that supports 
debug-on-error, you can drop into the debugger when the error occurs.

In general, this type of catch-and-reraise code is an antipattern for 
exception handling in Python, even though it's understandably required for 
sanity in "checked exception" languages like Java.

Outside of very high-level or very low-level code, try/except should be 
avoided - *especially* "bare" excepts or "except Exception".  Usually what 
you want is either try/finally, or not to catch errors at all.  The 
"middlemen" in the stack usually don't know enough about the nature of the 
error to handle it themselves, nor do they know enough about how the 
application should report errors to the user.



More information about the Dev mailing list