473,804 Members | 3,123 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to except the unexpected?

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.HTTPErr or. So I catch that. But then I get a urllib2.URLErro r, so
I catch that too. The next day, it encounters a urllib2.HTTPErr or, then a
IOError, a socket.timeout, httplib.Invalid URL,...

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.

--
René Pijlman
Mar 3 '06 #1
32 4425
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.HTTPErr or. So I catch that. But then I get a urllib2.URLErro r, so
I catch that too. The next day, it encounters a urllib2.HTTPErr or, then a
IOError, a socket.timeout, httplib.Invalid URL,...

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(IOErro r):
class HTTPError(URLEr ror, addinfourl):
class GopherError(URL Error):

This suggests that catching URLError should have caught your HTTPError,
so you might have the chronology backwards above.

E.g.:

py> class BobError(Except ion): pass
....
py> class CarolError(BobE rror): 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(E xception):
class NotConnected(HT TPException):
class InvalidURL(HTTP Exception):
class UnknownProtocol (HTTPException) :
class UnknownTransfer Encoding(HTTPEx ception):
class UnimplementedFi leMode(HTTPExce ption):
class IncompleteRead( HTTPException):
class ImproperConnect ionState(HTTPEx ception):
class CannotSendReque st(ImproperConn ectionState):
class CannotSendHeade r(ImproperConne ctionState):
class ResponseNotRead y(ImproperConne ctionState):
class BadStatusLine(H TTPException):

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
Mar 3 '06 #2
James Stroud wrote:
except URLError, HTTPException:


Aieee! This catches only URLError and binds the name HTTPException to
the detail of that error. You must write

except (URLError, HTTPException):

to catch both.

--
Ben Caradoc-Davies <be*@wintersun. org>
http://wintersun.org/
"Those who deny freedom to others deserve it not for themselves."
- Abraham Lincoln
Mar 4 '06 #3
Ben Caradoc-Davies wrote:
James Stroud wrote:
except URLError, HTTPException:

Aieee! This catches only URLError and binds the name HTTPException to
the detail of that error. You must write

except (URLError, HTTPException):

to catch both.


Oops.
Mar 4 '06 #4
In article <44************ ***********@per-qv1-newsreader-01.iinet.net.au >,
Ben Caradoc-Davies <be*@wintersun. org> wrote:
James Stroud wrote:
except URLError, HTTPException:


Aieee! This catches only URLError and binds the name HTTPException to
the detail of that error. You must write

except (URLError, HTTPException):

to catch both.


This exact issue came up just within the past week or so. I think that
qualifies it as a wart, but I think it's a double wart.

It's certainly a wart that the try statement syntax allows for such
ambiguity. But, I think it's also a wart in how the exceptions were
defined. I like to create a top-level exception class to encompass all the
possible errors in a given module, then subclass that. This way, if you
want to catch anything to goes wrong in a call, you can catch the top-level
exception class without having to enumerate them all.
Mar 4 '06 #5
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.HTTPErr or. So I catch that. But then I get a urllib2.URLErro r, so
I catch that too. The next day, it encounters a urllib2.HTTPErr or, then a
IOError, a socket.timeout, httplib.Invalid URL,...

How do you program robustly with these modules throwing all those
different (and sometimes undocumented) exceptions at you?
I do it by not micromanaging things. Presumably if you plan to catch an
exception, you have a specific procedure in mind for handling the
problem. Maybe a retry, maybe an alternate way of attempting the same
thing? Look to the code that you are putting in those except:
statements (or that you think you want to put in them) to decide what to
do about this situation. If each type of exception will be handled in a
different manner, then you definitely want to identify each type by
looking at the source or the docs, or doing it empirically.

Most of the time there isn't a whole lot of real "handling" going on in
an exception handler, but merely something like logging and/or reporting
it onscreen in a cleaner fashion than a traceback, then failing anyway.
This is one reason Java does get it wrong: 95% of exceptions don't
need and shouldn't have special handling anyway.

Good code should probably have a very small set of real exception
handling cases, and one or two catchalls at a higher level to avoid
barfing a traceback at the user.
A catchall seems like a bad idea, since it also catches AttributeErrors
and other bugs in the program.


Generally speaking this won't be a problem if you have your catchalls at
a fairly high level and have proper unit tests for the lower level code
which is getting called. You are doing unit testing, aren't you? ;-)

-Peter

Mar 4 '06 #6
On Sat, 04 Mar 2006 00:10:17 +0100, Rene Pijlman wrote:
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.HTTPErr or. So I catch that. But then I get a urllib2.URLErro r, so
I catch that too. The next day, it encounters a urllib2.HTTPErr or, then a
IOError, a socket.timeout, httplib.Invalid URL,...

How do you program robustly with these modules throwing all those
different (and sometimes undocumented) exceptions at you?
How robust do you want to be? Do you want to take a leaf out of Firefox
and Windows XP by generating an error report and transmitting it back to
the program maintainer?
A catchall seems like a bad idea, since it also catches AttributeErrors
and other bugs in the program.


ExpectedErrors = (URLError, IOError)
ErrorsThatCantH appen = (LookupError, ArithmeticError , AssertionError)

try:
process_things( )
except ExpectedErrors:
recover_from_er ror_gracefully( )
except ErrorsThatCantH appen:
print "Congratulation s! You have found a program bug!"
print "For a $327.68 reward, please send the following " \
"traceback to Professor Donald Knuth."
raise
except:
print "An unexpected error occurred."
print "This probably means the Internet is broken."
print "If the bug still occurs after fixing the Internet, " \
"it may be a program bug."
log_error()
sys.exit()

--
Steven.

Mar 4 '06 #7
Steven D'Aprano <st***@REMOVETH IScyber.com.au> writes:
try:
process_things( )
except ExpectedErrors:
recover_from_er ror_gracefully( )
except ErrorsThatCantH appen:
print "Congratulation s! You have found a program bug!"
print "For a $327.68 reward, please send the following " \
"traceback to Professor Donald Knuth."
raise
except:
print "An unexpected error occurred."
print "This probably means the Internet is broken."


But this isn't good, it catches asynchronous exceptions like the user
hitting ctrl-C, which you might want to handle elsewhere. What you
want is a way to catch only actual exceptions raised from inside the
try block.
Mar 4 '06 #8
On Fri, 03 Mar 2006 21:10:22 -0800, Paul Rubin wrote:
Steven D'Aprano <st***@REMOVETH IScyber.com.au> writes:
try:
process_things( )
except ExpectedErrors:
recover_from_er ror_gracefully( )
except ErrorsThatCantH appen:
print "Congratulation s! You have found a program bug!"
print "For a $327.68 reward, please send the following " \
"traceback to Professor Donald Knuth."
raise
except:
print "An unexpected error occurred."
print "This probably means the Internet is broken."


But this isn't good, it catches asynchronous exceptions like the user
hitting ctrl-C, which you might want to handle elsewhere. What you
want is a way to catch only actual exceptions raised from inside the
try block.

It will only catch the KeyboardInterru pt exception if the user actually
hits ctrl-C during the time the code running inside the try block is
executing. It certainly won't catch random ctrl-Cs happening at other
times.

The way to deal with it is to add another except clause to deal with the
KeyboardInterru pt, or to have recover_from_er ror_gracefully( ) deal with
it. The design pattern still works. I don't know if it has a fancy name,
but it is easy to describe:-

catch specific known errors that you can recover from, and recover from
them whatever way you like (including, possibly, re-raising the exception
and letting higher-level code deal with it);

then catch errors that cannot possibly happen unless there is a bug,
and treat them as a bug;

and lastly catch unexpected errors that you don't know how to handle and
die gracefully.

My code wasn't meant as production level code, nor was ExpectedErrors
meant as an exhaustive list. I thought that was too obvious to need
commenting on.

Oh, in case this also wasn't obvious, Donald Knuth won't really pay
$327.68 for bugs in your Python code. He only pays for bugs in his own
code. *wink*

--
Steven.

Mar 4 '06 #9
Steven D'Aprano <st***@REMOVETH IScyber.com.au> writes:
The way to deal with it is to add another except clause to deal with the
KeyboardInterru pt, or to have recover_from_er ror_gracefully( ) deal with
it.
I think adding another except clause for KeyboardInterru pt isn't good
because maybe in Python 2.6 or 2.6 or whatever there will be some
additional exceptions like that and your code will break. For example,
proposals have floated for years of adding ways for threads to raise
exceptions in other threads.

I put up a proposal for adding an AsynchronousExc eption class to
contain all of these types of exceptions, so you can check for that.
Oh, in case this also wasn't obvious, Donald Knuth won't really pay
$327.68 for bugs in your Python code. He only pays for bugs in his own
code. *wink*


The solution to that one is obvious. We have to get Knuth using Python.
Anyone want to write a PEP? ;-)
Mar 4 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1548
by: John J. Lee | last post by:
Bare "except:", with no exception specified, is nasty because it can easily hide bugs. There is a case where it seemed useful to me in the past. Now it seems like a bad idea to me (but I think I might still be confused about it, hence this post). It's this: When you're processing a input from a file-like object connected to an external source like a network connection, disk file etc, you have to expect broken, and often malicious,...
0
4247
by: Robert Mazur | last post by:
MySQL 5.0 alpha (binary install) on Solaris 9 -or- RedHat 8.0 mysql-connector-java-3.0.8-stable ----------------------- Is there something different going on with JDBC and the alpha version of MySQL 5.0? When trying to connect I am getting: ** BEGIN NESTED EXCEPTION **
1
1863
by: Ken | last post by:
Any thoughts on making explicit calls to unexpected()? My sense is that this function is really intended to be invoked automatically as part of exception handling. Are there times when explicit calls would be useful? Or would doing so introduce bug risks or maintanance headaches unnecessarily? Thanks for any opinions! Ken
2
2172
by: Gerhard Esterhuizen | last post by:
Hi, I am observing unexpected behaviour, in the form of a corrupted class member access, from a simple C++ program that accesses an attribute declared in a virtual base class via a chain of virtual method calls. To further complicate (or perhaps simplify) matters, some compilers (GCC and MingW) produce the expected behaviour, while others (MSVS 7.1) do not. I can only offer two explanations for my observations: 1. The Microsoft...
3
7426
by: Eric Anderson Vianet SAO | last post by:
hello all When i tried ´pg_dump -v -f dump.dmp dtbtransporte´ I got the error: pg_dump: restoring data for table tbdmovimento pg_dump: dumping out the contents of table tbdmovimento pg_dump: ERROR: unexpected chunk number 8 (expected 0) for toast value 6935693
3
3322
by: Anup Daware | last post by:
Hi Group, I am facing a strange problem here: I am trying to read xml response from a servlet using XmlTextWriter. I am able to read the read half of the xml and suddenly an exception: “Unexpected end of file while parsing Name has occurred†isbeing thrown. Following is the part o xml I am trying to read: <CHECK_ITEM_OUT>
7
9892
by: oscartheduck | last post by:
I have a small script for doing some ssh stuff for me. I could have written it as shell script, but wanted to improve my python skills some. RIght now, I'm not catching a syntax error as I'd like to. Here's my code: #!/usr/bin/env python import sys
4
1238
by: Chris Allen | last post by:
I am confused on one aspect of exception handling. If you specify the exception object type to match in an except statement it is possible to also obtain the exception object itself, but I can't figure out how to get the exception object when I don't specify a match. for example: this works and I can do what I like with the exception object (msg). but I can't do this with a simple except statment.
13
3622
by: bintom | last post by:
I ran the following simple code in C++ and got unexpected results: float f = 139.4; cout << f; Output: 139.399994;
0
10340
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10085
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9161
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7623
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5527
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5662
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4302
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3827
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2998
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.