Re: Simple way of handling errors
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
Re: Simple way of handling errors
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
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
> If it fails, you get both a straight-forward error message and a useful > traceback: > > Traceback (most recent call last): > File "", line 1, in > 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
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
On 2009-05-06 19:41:29 -0700, Steven D'Aprano 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 "", line 1, in 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
Re: Simple way of handling errors
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 "", line 1, in 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