[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