try: # some code except Exception, e: # Bad log.error("Uncaught exception!", e)Yet you need to do something like that, typically in the event loop of an application server, or when one library is calling into another library and needs to make sure that no exception escapes from the call, or that all exceptions are re-packaged in another type of exception.
The reason the above is bad is that Python badly screwed up their standard exception hierarchy.
__builtin__.object BaseException Exception StandardError ArithmeticError AssertionError AttributeError BufferError EOFError EnvironmentError ImportError LookupError MemoryError NameError UnboundLocalError ReferenceError RuntimeError NotImplementedError SyntaxError IndentationError TabError SystemError TypeError ValueErrorMeaning, if you try to catch all
Exceptions, you're also hiding real problems like syntax errors (!!), typoed imports, etc. But then what are you gonna do? Even if you wrote something silly such as:
try: # some code except (ArithmeticError, ..., ValueError), e: log.error("Uncaught exception!", e)You still wouldn't catch the many cases where people define new types of exceptions that inherit directly from
Exception. So it looks like your only option is to catch
Exceptionand then filter out things you really don't want to catch, e.g.:
try: # some code except Exception, e: if isinstance(e, (AssertionError, ImportError, NameError, SyntaxError, SystemError)): raise log.error("Uncaught exception!", e)But then nobody does this. And pylint still complains.
Unfortunately it looks like Python 3.0 didn't fix the problem :( – they only moved
GeneratorExitto be subclasses of
BaseExceptionbut that's all.
They should have introduced another separate level of hierarchy for those errors that you generally don't want to catch because they are programming errors or internal errors (i.e. bugs) in the underlying Python runtime.