Identifying exceptions that can be raised

Neil Benn neil.benn at arcor.de
Wed Nov 24 14:37:04 EST 2004


Hello,

          I too find the lack of finding exceptions that can be raised a 
problem (I'm a nasty old Java programmer as well!).  Java checked 
exceptions get a beating every so often but it's not as bad as always 
made out, see comments below:

>
> One of my puzzlements about Java 10 years ago or so was
> why it decided to go the "must declare every exception" route.

Well sort of there are two basic types of exceptions 'normal' exception 
and runtime exceptions - runtime exceptions do not need a try/catch 
around them.  These are your general case.

>
> Consider this simple and naive numeric integrator
>
> def integrate(f, start, end, n):
>   delta = (end-start)/float(n)
>   x = start + delta / 2
>   sum = 0.0
>   for i in range(n+1):
>     sum = sum + f(x)
>     x += delta
>   return sum / (n+1)
>
> That function cannot define all the exceptions that can be
> raised because f itself can raise an arbitrary exception.  Eg,
>
> def f1(x):
>   return 1/max(5-x, 0))  # Can raise a divide-by-zero error
>
> integrate(f1, 0, 10, 5)
>
> Java handles that case by saying you don't need to declare
> system exceptions.  

Not exactly true, you do have to check some systems exceptions - all 
those that are not runtime.  Divide by zero, type exceptions, null 
pointer exceptions are all examples of run-time.  For the others see later.

> Then consider
>
> def f2(x):
>   fname = os.path.join("/cache/directory", str(x))
>   if os.path.exists(fname):
>     return float(open(fname, "r").read())
>   y = _f2(x)
>   outfile = open(fname, "w")
>   try:
>     outfile.write(str(y))
>   finally:
>     outfile.close()
>   return y
>
> integrate(f2, 0, 10, 10)
>
> If the file is not readable, or the directory not readable,
> then this might raise an IOError.
>
> How does the 'integrate' function declare that it can raise
> any of the errors that the integrator function 'f' might raise?
>
> Again, IOError might be considered a system-level error
> such that it doesn't need declaring.  

IOError is a checked exception - if you want to do IO then you need to 
wrap it in a try catch or throw it to your caller.  This is because IO 
is inherently fault prone and you should be thinking about exceptions 
and unusual cases when doing IO.  However in Java, this sometimes falls 
over for example - ByteOutputStream, writes to a byte array - because it 
inherits OutStream, the read and write functions declare IOException 
which means you do sometimes have to write a meaningless try catch for 
this (its memory copying, won't fail due to IO).

> Then change it to
> polling some URL ("http://cache.server/" + str(x)) when the
> network is down, or getting it from some SQL database when
> the password is incorrect, or anything else that cannot be
> determined until actually calling f().

The first case uses OutputStream, checked exception - the second case 
uses JDBC which also has checked exceptions.

>
> It looks like the only thing to do is convert all such
> unhandled exceptions and wrap them in a catch-all generic
> exception.  I think I've seen people do that.  But if so,
> what's the point of having typed exceptions?

    Any java developer who does that should get pulled up at code review 
time, the only time I could ever recommend that is in a top level call 
when you want to catch all exceptions, log them and then apologise to 
the user profusely that your program screwed up!! 

>
> Curiously-y'rs,
>
>                 Andrew
>                 dalke at dalkescientific.com
>
    On a general point, the python/adults thingy that is often said - if 
followed correctly - removes the need for checked exceptions - if 
everyone coded correctly then you wouldn't need it.  However, I do find 
it frustrating that in a lot of python docs - the exceptions that can be 
thrown are not documented.  I know there are obvious null pointers, key 
errors and type exceptions but for example - what exceptions are thrown 
if I call socket.recv(1024) when there are no characters for me to 
receive??  The only way to determine this is to try it.  I miss a level 
of comfort that means that there may be a case which I haven't thought 
of which could cause my code to go kablooeee.  Eiffel's programming by 
contract goes one step further...

Cheers,

Neil






More information about the Python-list mailing list