Exception handling wart in Python

Leo Lipelis aeoo at myspamrealbox.com
Fri Nov 2 01:48:57 EST 2001


On Thu, 01 Nov 2001 22:03:42 -0500, Paul Rubin wrote:

> "Leo Lipelis" <aeoo at myrealbox.com> writes:
>> I'd like some help with an issue I have with Python.  Simply put, I
>> think having an exception mechanism is a waste if there is no tool that
>> will let you know which unhandled exceptions exist at point foo....
>> 
>> Considering that in Python exceptions are matched by identity instead
>> of equivalence, it's possible to track all the exception flows, right?
> 
> Of course not.  Since you can execute arbitrary strings, you can create
> new exception classes at runtime and throw them.

This is a non-argument.  It's like saying, you can access anything with a
pointer in C, thus you shouldn't use any tools that can warn you about
possible segfaults.  It's nonsense.  Just because you can dynamically
execute dynamically created strings with unknown exceptions doesn't mean
it's good to do so.  In 99.99% of Python code, the exceptions that are
thrown are well known in advance.  Even dynamically executed strings are
really not so dynamic, because, for example, they are often scripts that
could be exception-checked prior to execution.

> 
>> I agree with whoever said that a race horse doesn't belong in the glue
>> factory.  It seems like Python is being used for serious programming,
>> and it seems to me, if it supports exceptions, it should support them
>> all the way.  It's fairly pointless to provide exceptions if you really
>> never know whether you handle all the relevant exceptions or not,
>> without the ugly, bad, and stupid except: foo() statements to catch
>> *all* exceptions.
> 
> I don't understand the problem.  The whole idea of an exception is it's
> something you don't have to know how to deal with.  You catch the

This is simply wrong.  That's not the idea.  The whole idea of exceptions
is that you will know 99.99% of the time which exceptions you should
handle, so that you can intelligently decide where to handle them, or
whether to handle them at all, and how to handle them.  This decision is
impossible if you don't know what is being thrown at a certain point.  In
reality, there is no reason why you shouldn't know it.

Then, you can deal with various exceptions differently.  For some, you can
just log them and keep going.  For others, you may request the user to try
again.  For yet others you can attempt automatic recovery.  All this is
impossible if you don't know what exceptions you're dealing with.

> exceptions you can handle, and leave the rest for higher levels of the
> program.  You can always catch all the exceptions, and then if you get
> something you can't deal with, re-raise it.

This is also nonsense.  Sure you can catch all exceptions and examine them.
But in order to code anything intelligent, you again have to know ahead of
time what these exceptions might be.  At the very *LEAST* you need a list
of *all possible* exceptions in an entire Python code base, including
Python standard module library!  But how much better would it be if you
could narrow the scope to the most likely exceptions.

except: # foo is not bound here... because I am catching ALL exceptions
    if (not self.__canHandleException(foo)): # what is foo?
        raise foo # and how can you re-raise it here?  what is foo?

...

def __canHandleException(foo):
    if type(foo) == BlahType: # ahh, but you have to know about BlahType!
        return 1
    elif type(foo) == BuzType: # again, you have to know about BuzType!
        return 1
    elif type(foo) == OtherType: # and how do you know about OtherType?
        return 1
    else:
        return 0

The above is not very smart and in fact, I don't even know how to reference
the exception object when you use catch-all "except:".  Even if it can be
done, it doesn't accomplish anything.

I'd much rather read this:

except BlahType:
    self.__handleBlahError()
except BuzType:
    self.__handleBuzError()
except OtherType:
    self.__handleOtherError()

But, no matter how you write it, you *still have to know* what exceptions
you need to handle.  You can't magically decide it at run time, nor do you
need to, nor should you.

The dynamic nature of Python is absolutely not a reason for such a
lucklaster handling of exceptions in Python.  Let's get this argument out
of the way, because I don't think it's even worth discussing further,
unless someone can demonstrate that in 99.99% of cases you really can't
possibly know what exceptions you should handle anyway.  Again, just
because it's possible to use the language in a twisted way, doesn't mean
that the other 99.99% of exceptions should be penalized by not having a
tool that automatically warns you about unhandled exceptions.

The very uncommon case where someone decides to create and throw random
exceptions, just for fun, should not be protected or used as an excuse to
deny us the very useful service of warning about unhandled exceptions.  Nor
should this excuse be used to diminish the importance of such a tool.  I
say that without such a tool, exceptions in Python are pointless at worst,
and are very awkward to use at best.  Documentation is *not* the answer,
and I already explained why not in my original post.



More information about the Python-list mailing list