Re: Simple way of handling errors

2009-05-07 Thread Peter Otten
TomF wrote:

 As a relative newcomer to Python, I like it a lot but I'm dismayed at
 the difficulty of handling simple errors.  In Perl if you want to
 anticipate a file-not-found error you can simply do:
 
 open($file)  or die(open($file): $!);
 
 and you get an intelligible error message.  In Python, to get the same
 thing it appears you need at least:
 
 try:
 f=open(file)
 except IOError, err:
 print open(%s): got %s % (file, err.strerror)
 exit(-1)
 
 Is there a simpler interface or idiom for handling such errors?  I
 appreciate that Python's exception handling is much more sophisticated
 but often I don't need it.
 
 -Tom

While you are making the transition you could write

from perl_idioms import open_or_die

f = open_or_die(does-not-exist)


with the perl_idioms module looking like

import sys

def open_or_die(*args):
try:
return open(*args)
except IOError, e:
sys.exit(e)

Peter

--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-07 Thread Stephen Hansen
 If it fails, you get both a straight-forward error message and a useful
 traceback:

 Traceback (most recent call last):
  File stdin, line 1, in module
 IOError: [Errno 2] No such file or directory: 'foomanchu'


 The only reason you would bother going to the time and effort of catching
 the error, printing your own error message, and then exiting, is if you
 explicitly want to hide the traceback from the user.


Unfortunately, I find that even halfway technically trained
(not necessarily naturally inclined or talented, but trained) users are
utterly unable to read tracebacks in real world situations. I had to put up
a rather big guide on how to read and interpret even the simplest ones
complete with color coding, how to pick out a traceback visually, what
line to focus your attention on (the last), and how trying to /read/ it
instead of immediately sending it to me as if it were an opaque symbol
containing secret knowledge only I can make sense of, generally saves you
time in debugging issues. I'm not talking about esoteric tracebacks either
resulting from real bugs and stuff. I'm talking about 'file not found'
'permission denied' IO/OS level ones that should give serious hints at
things people should check/diagnose themselves.

There's a serious, oh my god, traceback, /eyes glazed over/ reaction all
around. Now these aren't unix people or command line people (except my
rote), but still.

I don't quite find printing out tracebacks to stdout or stderr ever
acceptable :( Especially if its an expected error condition (file not found
is a very good example of that).

I route all my tracebacks into log files for diagnosing later (people also
can not be relied upon to say anything but 'traceback' when they see one: so
storing it for later is vital. They read the first word and stop. The
thought of most-significant-information at the bottom is a difficult thing,
alas)

Anyways. ;-) That's just my experience.

As to the OP: try/except is how you do it in Python. There's no shorter or
easier way; exceptions are how Python handles failure-states (even
soft/expected errors quite often) and it does so pervasively (but not
universally).

--S
--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-07 Thread Steven D'Aprano
On Wed, 06 May 2009 20:21:38 -0700, TomF wrote:

 The only reason you would bother going to the time and effort of
 catching the error, printing your own error message, and then exiting,
 is if you explicitly want to hide the traceback from the user.
 
 Well, to me, exposing the user to such raw backtraces is unprofessional,
 which is why I try to catch user-caused errors.  But I suppose I have an
 answer to my question.

That depends on your audience. Not every program is written to be used 
for a technical incompetent audience. Some users actually *want* to see 
the errors.

But certainly there are large classes of applications where you do want 
to suppress the traceback. That's why I said if you explicitly want to 
hide the traceback from the user rather than don't do this.

The idiom I use is to wrap the *entire* application in a single 
try...except block, and then put all your user-friendly error handling in 
one place, instead of scattered over the entire application:


try:
main(sys.argv[1:])
except KeyboardInterrupt, SystemExit:
raise
except Exception, e:
log(e)
print sys.stderr, str(e)
sys.exit(1)



Hope this helps.



-- 
Steven

--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-07 Thread TomF

On 2009-05-07 01:01:57 -0700, Peter Otten __pete...@web.de said:


TomF wrote:


As a relative newcomer to Python, I like it a lot but I'm dismayed at
the difficulty of handling simple errors.  In Perl if you want to
anticipate a file-not-found error you can simply do:

open($file)  or die(open($file): $!);

and you get an intelligible error message.  In Python, to get the same
thing it appears you need at least:

try:
f=open(file)
except IOError, err:
print open(%s): got %s % (file, err.strerror)
exit(-1)

Is there a simpler interface or idiom for handling such errors?  I
appreciate that Python's exception handling is much more sophisticated
but often I don't need it.

-Tom


While you are making the transition you could write

from perl_idioms import open_or_die

f = open_or_die(does-not-exist)


with the perl_idioms module looking like

import sys

def open_or_die(*args):
try:
return open(*args)
except IOError, e:
sys.exit(e)

Peter


Thanks.  Rolling my own error module for common errors may be the best 
way to go.


-Tom

--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-07 Thread Matt Nordhoff
Steven D'Aprano wrote:
 On Wed, 06 May 2009 20:21:38 -0700, TomF wrote:
 
 The only reason you would bother going to the time and effort of
 catching the error, printing your own error message, and then exiting,
 is if you explicitly want to hide the traceback from the user.
 Well, to me, exposing the user to such raw backtraces is unprofessional,
 which is why I try to catch user-caused errors.  But I suppose I have an
 answer to my question.
 
 That depends on your audience. Not every program is written to be used 
 for a technical incompetent audience. Some users actually *want* to see 
 the errors.
 
 But certainly there are large classes of applications where you do want 
 to suppress the traceback. That's why I said if you explicitly want to 
 hide the traceback from the user rather than don't do this.
 
 The idiom I use is to wrap the *entire* application in a single 
 try...except block, and then put all your user-friendly error handling in 
 one place, instead of scattered over the entire application:
 
 
 try:
 main(sys.argv[1:])
 except KeyboardInterrupt, SystemExit:

That should be:

except (KeyboardInterrupt, SystemExit):

;-D

 raise
 except Exception, e:
 log(e)
 print sys.stderr, str(e)
 sys.exit(1)
 
 
 
 Hope this helps.
-- 
--
http://mail.python.org/mailman/listinfo/python-list


Simple way of handling errors

2009-05-06 Thread TomF
As a relative newcomer to Python, I like it a lot but I'm dismayed at 
the difficulty of handling simple errors.  In Perl if you want to 
anticipate a file-not-found error you can simply do:


open($file)  or die(open($file): $!);

and you get an intelligible error message.  In Python, to get the same 
thing it appears you need at least:


try:
   f=open(file)
except IOError, err:
   print open(%s): got %s % (file, err.strerror)
   exit(-1)

Is there a simpler interface or idiom for handling such errors?  I 
appreciate that Python's exception handling is much more sophisticated 
but often I don't need it.


-Tom

--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-06 Thread Steven D'Aprano
On Wed, 06 May 2009 16:40:19 -0700, TomF wrote:

 As a relative newcomer to Python, I like it a lot but I'm dismayed at
 the difficulty of handling simple errors.  In Perl if you want to
 anticipate a file-not-found error you can simply do:
 
 open($file)  or die(open($file): $!);
 
 and you get an intelligible error message.  In Python, to get the same
 thing it appears you need at least:
 
 try:
 f=open(file)
 except IOError, err:
 print open(%s): got %s % (file, err.strerror)
 exit(-1)


Functions never fail silently in Python. (At least built-in functions 
never fail silently. Functions you write yourself can do anything you 
want.)


The canonical way of doing open or die in Python is to just call open:

f = open(filename)

If it fails, you get both a straight-forward error message and a useful 
traceback:

Traceback (most recent call last):
  File stdin, line 1, in module
IOError: [Errno 2] No such file or directory: 'foomanchu'

 
The only reason you would bother going to the time and effort of catching 
the error, printing your own error message, and then exiting, is if you 
explicitly want to hide the traceback from the user.

Oh, and if you do that, I recommend that you print to stderr instead of 
stdout:

print sys.stderr, open(%s): got %s % (file, err.strerror)

or 

sys.stderr.write(open(%s): got %s\n % (file, err.strerror))



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Simple way of handling errors

2009-05-06 Thread TomF
On 2009-05-06 19:41:29 -0700, Steven D'Aprano 
ste...@remove.this.cybersource.com.au said:



On Wed, 06 May 2009 16:40:19 -0700, TomF wrote:


As a relative newcomer to Python, I like it a lot but I'm dismayed at
the difficulty of handling simple errors.  In Perl if you want to
anticipate a file-not-found error you can simply do:

open($file)  or die(open($file): $!);

and you get an intelligible error message.  In Python, to get the same
thing it appears you need at least:

try:
f=open(file)
except IOError, err:
print open(%s): got %s % (file, err.strerror)
exit(-1)



Functions never fail silently in Python. (At least built-in functions
never fail silently. Functions you write yourself can do anything you
want.)


Well, yes, I'm aware that if you don't handle errors Python barfs out a 
backtrace.



If it fails, you get both a straight-forward error message and a useful
traceback:

Traceback (most recent call last):
  File stdin, line 1, in module
IOError: [Errno 2] No such file or directory: 'foomanchu'

The only reason you would bother going to the time and effort of catching
the error, printing your own error message, and then exiting, is if you
explicitly want to hide the traceback from the user.


Well, to me, exposing the user to such raw backtraces is 
unprofessional, which is why I try to catch user-caused errors.  But I 
suppose I have an answer to my question.


Thanks,
-Tom

--
http://mail.python.org/mailman/listinfo/python-list