exception handling in complex Python programs

dbpokorny at gmail.com dbpokorny at gmail.com
Tue Aug 19 20:07:39 CEST 2008


On Aug 19, 10:19 am, eliben <eli... at gmail.com> wrote:

> P.S. There's a common case where a method is passed a filename, to do
> something with a file (say, read data). Should the method catch the
> errors possibly thrown by open(), or leave it to the caller ?

You want to look up Easier to Ask Forgivness than Permission (EAFP)
which is touted as the "canonical" error-handling paradigm for Python.
This would give rise to the following function:

  def do_something(filename):
    try:
      f = open(filename)
    except IOError:
      return err("File %s not found" % filename)
    ...

where err is a function that generates an error object that your
application understands. I personally think this is sloppy because you
have to couple the exception type with the function --- between file()
and open() in Python 2 and 3, a NameError is thrown with open() in
Python 3 and an IOError is thrown in the other three cases <bashes
head against keyboard>. The alternative is

  def do_something(filename):
    if not os.access(filename,os.R_OK):
      return err(...)
    f = open(filename)
    ...

or, (and this last one I actually used for a web application)

  def do_something(filename):
    if not os.access(filename,os.R_OK):
      raise MyApplicationsExceptionType("File not found...")
    f = open(filename)
    ...

The last one has the advantage that you can write a request handler
like this

  def handle_http_request(...):
    func = specific_handler_func(...)
    try:
      response = func(...)
      return response
    except MyApplicationsExceptionType as exc: #3.0 syntax
      return error_response(exc,...)

Exceptions you don't expect (i.e. bugs) will get handled by the web
app framework, but you get to handle your own exceptions. Raising your
own exception type can also be employed with the EAFP approach like
this:

  def do_something(filename):
    try:
      f = open(filename)
    except IOError:
      raise MyApplicationsExceptionType("File %s not found" %
filename)
    ...

If you are writing a library (for instance using a file for persistent
storage), then the answer to your question is "don't catch the
exception." Clients will expect the usual exception to be thrown when
a bad file name is passed.

David



More information about the Python-list mailing list