[Tutor] How to notify/handle an error?

Steven D'Aprano steve at pearwood.info
Sun Oct 31 13:57:04 CET 2010


dave p. guandalino wrote:
> Which of the following ways is better to handle something wrong? Many
> thanks.

It depends on what you are trying to do.


> # First:
> def is_valid_project():
>     # Do checks and valorize is_a_valid_project accordingly
>     return is_a_valid_project # True / False

Do you mean "validate" rather than "valorize"?

> # caller side
> if is_valid_project():
>     pass # do stuffs with valid project
> else:
>     print "error"

This is not the best approach. Never (well, *almost* never) use print 
for printing error messages. Here the caller should do one of these:

# caller #1
if is_valid_project():
     do_something_with_valid_project()
else:
     do_something_else()

# caller #2
if is_valid_project():
     do_something_with_valid_project()
else:
     # this is a fatal error, bail out
     raise SomeException()


This general technique is called "Look before you leap" -- you're 
checking whether something is safe before attempting to do it. If it is 
safe, you continue, otherwise you take an alternative action (often just 
to raise an error and stop processing).



> # Second solution:
> def is_valid_project():
>     # Do checks and valorize is_a_valid_project accordingly
>     if not is_a_valid_project:
>         raise NotAValidProject
> 
> # caller side
> try:
>     is_valid_project()
>     pass # do stuffs with valid project
> except NotAValidProject:
>     print "error"

This general technique is called "Easier to ask forgiveness than 
permission" -- just try to do what you want, and if it fails, catch the 
exception and do something else.

Again, you should almost never catch an exception just to print an error 
message. Very rare exception to this rule: at the *very top level* of an 
application, you might catch the exception, log the technical details, 
display a user-friendly message to the user, and then exit the 
application. When you use raise, Python does nearly all of this for you. 
It won't log the failure, and the message is a technical traceback aimed 
at programmers rather than end-users, but it prints an error message and 
exits the application.

Better would be:


# caller #3
is_valid_project()  # will raise an exception if there is a problem
do_something_with_valid_project()


# caller #4
try:
     is_valid_project()
except NotAValidProject:
     do_something_else
else:
     # no exception occurred
     do_something_with_valid_project()


In Python, try blocks are very efficient, but actually catching an 
exception is moderately costly. So the general rule is, if you expect 
most cases to succeed, and failures to be rare, it is better to use a 
try...except block and the "Easier to ask forgiveness" strategy. If you 
expect failures to be common, it is better to "Look Before You Leap".


-- 
Steven



More information about the Tutor mailing list