One common-place thing I've noticed in a lot of python code is that every package or module has a main Error class, and all sub-types inherit from that class. So you just catch mylib.Error, and you're going to catch all the exceptions that package generates directly.
There seems to be a lot of concern about what exceptions a functions might throw, and what to do when it happens. The way I see it, there are only two types of exceptions: those you can recover from, and those you can't. The only ones -really- worth catching are those you can recover from. There's a middle-ground type of 'cleanup', to free any resources, but those generally go in a finally block, not an except block. For the ones you can't handle, it doesn't matter if you catch them or not. If you catch them, what do you do? Log an error message, then rethrow it. You're still throwing an exception, so you haven't really gained anything. You might repackage it and put additional information in the exception so you can do something at a higher level. What that is, I don't know. I don't think I've ever passed information up in an exception that was of use to the program, and I'm hard pressed to think of any information you could provide that could - fix- the problem. If you can derive recoverable information, then why rethrow? Thats pretty much a recoverable situation, so there's not need to rethrow. In java, there are checked exceptions, which are nice - they tell you what a function might throw, so you know what to catch. I don't think this improves the quality of anything, though. It just annoys the developer. What they end up doing is writing an application-specific exception class, and -everything- gets rethrown as that, and everything begins to declare it throws AppError. Whats worse is that you have heavily, heavily repackaged exceptions: SQLError -> AppError -> MessageError -> AppError -> MessageError (yes, i've seen this before). That is almost completely useless. Sure, you could dig down to SQLError, but how do you know to do that? If you knew how far you should dig down, that means you know what the problem was, in which case, you could have prevented it or aborted early. Whats worse, if you have all these re-packaging catch blocks and they just log something generic, which becomes common with all the catching going on. "Couldn't do foo!", "Bar operation failed!", or "Couldn't fetch filters from database" (why? We don't know, its catching an AppError instead of something more specific), and then they rethrow the exception. While trying to debug something not-during development, those messages are completely useless, in fact, they're more than useless. They're just more cruft to sift through in a log file. Additionally, most root causes of an error are going to originate where the input comes from the user. Handling anything at levels deeper than that isn't going to gain you much. PrepareQuery threw an error because of a missing field? Thats great. Where'd it come from? There are 100 calls to PrepareQuery. There's only a few calls to ReadUserInput(), and a single informative log message of "Query failed, unknown field; fields=a, b, c" is much better than 100 lines of traceback smattered with "Unknown field" and "Unable to prepare query". Finally, they give a false sense of security. "I'm catching everything it could throw, so everything will be ok if an exception is thrown!" I guess thats true. I guess. The only real advantage is the whole program won't crash with the ever-helpful, single line of "Segmentation fault." An improvement, but it doesn't prevent anything. In a complex system, an error can occur in any function at anytime. Adding 'throws' to a method definition doesn't change that. I guess my point is: everything Chris Mellon said was spot on. -- http://mail.python.org/mailman/listinfo/python-list