How to except the unexpected?
James Stroud
jstroud at ucla.edu
Fri Mar 3 18:44:23 EST 2006
Rene Pijlman wrote:
> One of the things I dislike about Java is the need to declare exceptions
> as part of an interface or class definition. But perhaps Java got this
> right...
>
> I've writen an application that uses urllib2, urlparse, robotparser and
> some other modules in the battery pack. One day my app failed with an
> urllib2.HTTPError. So I catch that. But then I get a urllib2.URLError, so
> I catch that too. The next day, it encounters a urllib2.HTTPError, then a
> IOError, a socket.timeout, httplib.InvalidURL,...
>
> How do you program robustly with these modules throwing all those
> different (and sometimes undocumented) exceptions at you?
>
> A catchall seems like a bad idea, since it also catches AttributeErrors
> and other bugs in the program.
>
The relevant lines of urllib2, for example, look as such:
class URLError(IOError):
class HTTPError(URLError, addinfourl):
class GopherError(URLError):
This suggests that catching URLError should have caught your HTTPError,
so you might have the chronology backwards above.
E.g.:
py> class BobError(Exception): pass
...
py> class CarolError(BobError): pass
...
py> try:
... raise CarolError
... except BobError:
... print 'got it'
...
got it
Now,
% cat httplib.py | grep -e '^\s*class'
produces the following at one point in its output:
class HTTPException(Exception):
class NotConnected(HTTPException):
class InvalidURL(HTTPException):
class UnknownProtocol(HTTPException):
class UnknownTransferEncoding(HTTPException):
class UnimplementedFileMode(HTTPException):
class IncompleteRead(HTTPException):
class ImproperConnectionState(HTTPException):
class CannotSendRequest(ImproperConnectionState):
class CannotSendHeader(ImproperConnectionState):
class ResponseNotReady(ImproperConnectionState):
class BadStatusLine(HTTPException):
Which suggests that "try: except HTTPException:" will be specific enough
as a catchall for this module.
The following, then, should catch everything you mentioned except the
socket timeout:
try:
whatever()
except URLError, HTTPException:
alternative()
But it seems to me that working with the internet as you are doing is
fraught with peril anyway.
James
More information about the Python-list
mailing list