471,338 Members | 1,511 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,338 software developers and data experts.

Hiding tracebacks from end-users

I'm writing a command-line application that is meant to be relatively
user friendly to non-technical users.

(Some wags might like to say that "user friendly" and "command-line
application" are, by definition, contradictory. I disagree.)

Consequently, I'd like to suppress Python's tracebacks if an error does
occur, replacing it with a more friendly error message. I'm doing
something like this:

try:
setup()
do_something_useful()
except KeyboardInterrupt:
print >>sys.stderr, "User cancelled"
sys.exit(2)
except Exception, e:
if expert_mode:
# experts get the full traceback with no hand-holding.
raise
else:
# print a more friendly error message
if isinstance(e, AssertionError):
msg = "An unexpected program state occurred"
elif isinstance(e, urllib2.HTTPError):
msg = "An Internet error occurred"
else:
# catch-all for any other exception
msg = "An error occurred"
print>>sys.stderr, msg
print>>sys.stderr, e
sys.exit(1)
else:
sys.exit(0)

Is this a good approach? Is there another way to suppress the traceback
and just print the error message?
--
Steven.
Oct 23 '07 #1
4 9670
On Oct 23, 7:07 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
I'm writing a command-line application that is meant to be relatively
user friendly to non-technical users.

(Some wags might like to say that "user friendly" and "command-line
application" are, by definition, contradictory. I disagree.)

Consequently, I'd like to suppress Python's tracebacks if an error does
occur, replacing it with a more friendly error message. I'm doing
something like this:

try:
setup()
do_something_useful()
except KeyboardInterrupt:
print >>sys.stderr, "User cancelled"
sys.exit(2)
except Exception, e:
if expert_mode:
# experts get the full traceback with no hand-holding.
raise
else:
# print a more friendly error message
if isinstance(e, AssertionError):
msg = "An unexpected program state occurred"
elif isinstance(e, urllib2.HTTPError):
msg = "An Internet error occurred"
else:
# catch-all for any other exception
msg = "An error occurred"
print>>sys.stderr, msg
print>>sys.stderr, e
sys.exit(1)
else:
sys.exit(0)

Is this a good approach? Is there another way to suppress the traceback
and just print the error message?

--
Steven.
No, I think with try-catch statements only. But this is a good
approach and you have nothing to worry about.

Oct 23 '07 #2
On Oct 23, 11:07 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
I'm writing a command-line application that is meant to be relatively
user friendly to non-technical users.

(Some wags might like to say that "user friendly" and "command-line
application" are, by definition, contradictory. I disagree.)

Consequently, I'd like to suppress Python's tracebacks if an error does
occur, replacing it with a more friendly error message. I'm doing
something like this:

try:
setup()
do_something_useful()
except KeyboardInterrupt:
print >>sys.stderr, "User cancelled"
sys.exit(2)
except Exception, e:
if expert_mode:
# experts get the full traceback with no hand-holding.
raise
else:
# print a more friendly error message
if isinstance(e, AssertionError):
msg = "An unexpected program state occurred"
elif isinstance(e, urllib2.HTTPError):
msg = "An Internet error occurred"
else:
# catch-all for any other exception
msg = "An error occurred"
print>>sys.stderr, msg
print>>sys.stderr, e
sys.exit(1)
else:
sys.exit(0)

Is this a good approach? Is there another way to suppress the traceback
and just print the error message?

--
Steven.
I think this is a good approach too. But why are you using If
statements for some errors? You should be able to do something like
this:

try:
do something
except AssertionError:
do something
except ZeroDivisionError:
do something
except urllib2.HTTPError:
do something
except...

etc, etc...

If you know what errors to expect, make them into a specific except
block. And leave the catchall on there for the exceptions you've
forgotten.

Mike

Oct 23 '07 #3
On Oct 23, 12:07 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:

....
if expert_mode:
# experts get the full traceback with no hand-holding.
raise
else:
# print a more friendly error message
....

Another approach is to always print a friendly error message,
but append the traceback to a log file (see the traceback
module for how to do that.) The friendly error message can
include a note that full information is available in the log
file.

The advantage of that is that you capture critical information
that is otherwise lost when a non-expert user hits the exception.
For intermittent bugs that are hard to reproduce, this can be
a lifesaver - especially when your favorite non-expert user
seems to have a knack for generating errors that you can't figure
out how to create ;-)

Alan

Oct 23 '07 #4
Steven D'Aprano <st***@REMOVE-THIS-cybersource.com.auwrote:
I'm writing a command-line application that is meant to be relatively
user friendly to non-technical users.
Consequently, I'd like to suppress Python's tracebacks if an error does
occur, replacing it with a more friendly error message. I'm doing
something like this:
>try:
setup()
do_something_useful()
except KeyboardInterrupt:
print >>sys.stderr, "User cancelled"
sys.exit(2)
except Exception, e:
if expert_mode:
# experts get the full traceback with no hand-holding.
raise
else:
# print a more friendly error message
if isinstance(e, AssertionError):
msg = "An unexpected program state occurred"
elif isinstance(e, urllib2.HTTPError):
msg = "An Internet error occurred"
else:
# catch-all for any other exception
msg = "An error occurred"
print>>sys.stderr, msg
print>>sys.stderr, e
sys.exit(1)
else:
sys.exit(0)
Is this a good approach? Is there another way to suppress the traceback
and just print the error message?
There's traceback.format_exception_only().

If the exception value is a unicode object containing characters which
can't be encoded by sys.stderr's encoding, the code above will fail
(give an ugly traceback and fail to display the error message).

format_exception_only() would be less ugly, but it would still fail to
display the error message. So it's safest to check for this case
explicitly and encode with backslashreplace or similar.

In this situation I use bare except and sys.exc_info, rather than
'except Exception', because there are still libraries out there which
raise objects which aren't instances of Exception.

-M-

Oct 24 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Maxwell Hammer | last post: by
reply views Thread by Timothy Smith | last post: by
6 posts views Thread by harrylmh | last post: by
reply views Thread by Nathan | last post: by
5 posts views Thread by George Sakkis | last post: by
11 posts views Thread by JJ297 | last post: by

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.