[Tutor] parsing errors for try/except handling

Magnus Lyckå magnus@thinkware.se
Fri May 9 07:22:10 2003


At 04:02 2003-05-09 -0400, Bruce Dykes wrote:
>def nfscheck(entry):
>     try:
>         tn=telnetlib.Telnet(entry[0])
>     except Exception, e:
>         response=e[1]

Not all instances of Exception will have slices. If you get another kind
of exception than a socket.error, it's likely that you end up with an
IndexError. (It doesn't have to be a mistyping in your code that causes
it, even if that's what I demonstrate below.)

 >>> try:
...     tn+=telnetlib.Telnet(entry[0])
... except Exception, e:
...     response = e[1]
...     print response
...
Traceback (most recent call last):
   File "<interactive input>", line 4, in ?
IndexError: tuple index out of range

In this case it was "tn+=..." which caused a NameError, but you
can't do e[1] on a NameError, so you get a strange IndexError
in the except clause, and no good indication of what you did wrong.
The same thing would happen if entry was None for instance.

Only catch the exceptions that you are prepared to handle!

>     else:
>         tn.read_until('login: ',15)
>         tn.write(entry[1]+'\n')
>         tn.read_until('Password: ',15)
>         tn.write(entry[2]+'\n')
>         tn.read_until('$',15)
>         tn.write('ls\n')
>         response=tn.read_until('$',15)
>         tn.write('exit\n')
>     return response

What if your "read_until" etc leads to exceptions? Where do you
catch that? And with your previous finally version, you might get
into situations where you try to return a "response" that wasn't
defined. Maybe you should have something like...

import telnetlib
import socket
try:
     response = "Unexpected Error in ???: Please Contact Support!"
     try:
         tn=telnetlib.Telnet(entry[0])
         tn.read_until('login: ','15')
         tn.write(entry[1]+'\n')
         tn.read_until('Password: ','15')
         tn.write(entry[2]+'\n')
         tn.read_until('$','15')
         tn.write('ls\n')
         response=tn.read_until('$','15')
         tn.write('exit\n')
     except socket.error, e:
         response = e[1]
finally:
    return response

or maybe even better...

import telnetlib, socket, traceback, sys
try:
     response = ("If you see this message,\n"
                 "the programmer's wife made a mistake... :(")
     try:
         tn=telnetlib.Telnet(entry[0])
         tn.read_until('login: ','15')
         tn.write(entry[1]+'\n')
         tn.read_until('Password: ','15')
         tn.write(entry[2]+'\n')
         tn.read_until('$','15')
         tn.write('ls\n')
         response=tn.read_until('$','15')
         tn.write('exit\n')
     except socket.error, e:
         response = e[1]
     except:
         response = ("Unexpected Error, please report to admin:\n" +
                     "".join(traceback.format_tb(sys.exc_traceback)))
finally:
    return response

The users will hate the "Unexpected Error" message, because it's
incomprehensible to them, but in this case, where you are obviously
prepared to returned with unfinished business, it's probably
better than an exception. It's probably better if the bulk of
the error is somehow sent to someone who understands it, and the
user is just presented with a less technical error mesaage than
a Python traceback, but I'll leave that as an exercise for the reader.

Hang on. *Most* of those error messages are more or less incomprehensible
to normal users... 'getaddrinfo failed' Huh?, 'Connection refused' What's
a "Connection"? Why was it refused? This would make much more sense as
"Unable to connect to Telnet server on %s" % entry[0] , 'Operation timed
out' Operation? Are we having surgery? I guess they all need refinement,
if norma lusers should use the program.


--
Magnus Lycka (It's really Lyck&aring;), magnus@thinkware.se
Thinkware AB, Sweden, www.thinkware.se
I code Python ~ The shortest path from thought to working program