Over a million developers have joined DZone.
Platinum Partner

Everything you need to know about Python exceptions

· Web Dev Zone

The Web Dev Zone is brought to you by Stormpath—offering a pre-built Identity API for developers. Easily build powerful user management, authentication, and authorization into your web and mobile applications. Download this Forrester report on the new landscape of Customer Identity and Access Management.

Exceptions are the modern way to substitute error codes to signal errors, and are mainly present in object-oriented languages both static and dynamic. Exceptions are also a first-class mechanism in Python.

Implementation: similar to other languages

Exceptions are objects of particular classes dedicated only to model errors. When raised (or thrown, depending on the jargon), they interrupt the normal flow of the code: they bubble up to the calling method (and the method above that in the stack trace) until they:
  • are handled via a specific construct (caught).
  • Get at the topmost level, causing the program to terminate.
Exceptions, like many language classes, are organized in a hierarchy so that catching can work at different level of precision: you can specify you want to handle a ArithmeticError if you are in your own module, while at the highest level you'll probably manage any Exception instance to avoid termination. Even in catastrophic cases, it's nicer to log an error and displaying a real error message to the user instead of an exception.


The try/except construct handles exceptions in Python:
languages = ["c", "python", "php", "java"]
print languages.index("python")
    print languages.index("English")
except ValueError:
    print "English is not a *programming* language"

In many languages except is called catch. Of course multiple except blocks can be specified to handle different exceptions.

raise raises your own exception, which should be an object of a class descending from Exception, usually named with the *Error suffix:

    raise ValueError("English")
except ValueError:
    print "English is not a *programming* language"

raise called without arguments just raises again the last caught exception:

    raise ValueError("English")
except ValueError as e:

except can also bind a local variable to the exception if you need to inspect it:

    raise ValueError("English")
except ValueError as e:
    print e.__class__           # <type 'exceptions.ValueError'>
    print sys.exc_info()        # the tuple (<type 'exceptions.ValueError'>, ValueError('English',), <traceback object at 0xb779b874>)

You can add an else block to perform some work in the absence of errors:

    print languages.index("c")
except ValueError:
    print "C is not a *programming* language"
    print "C is a programming language"

finally defines a block of code which will always be executed, even if you return early from the try, or do not specify an except block:

    print languages.index("c")
except ValueError:
    print "C is not a *programming* language"
    print "By the way, there were %s languages" % (len(languages), )

finally is meant to clean up even if the worst case scenario happens.

The traceback module is handy for displaying debug information about the last caught exception:

    print languages.index("English")
except ValueError:
    traceback.print_stack()     # only the stack trace

The hierarchy of built-in exceptions

At the Python's reference manual you'll find a full hierarchy of built-in exceptions, useful when catching them or when deciding which class your exception should inherit from.

Here's a condensed version of the hierarchy, omitting many minor exceptions:

 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    +-- ImportError
      |    +-- LookupError
      |    |    +-- IndexError
      |    |    +-- KeyError
      |    +-- RuntimeError
      |    |    +-- NotImplementedError
      |    +-- SyntaxError
      |    +-- SystemError
      |    +-- TypeError
      |    +-- ValueError
      +-- Warning
           +-- DeprecationWarning
           +-- SyntaxWarning

Note that since Python is usually interpreted (or compiled just in time in .pyc modules) there are even errors related to the syntax or issues in importing modules.

When defining your own exception, you should extend at least Exception. Other BaseException derivatives are reserved and should not be caught by any other than the interpreter, like SystemExit.

The Web Dev Zone is brought to you by Stormpath—offering a pre-built, streamlined User Management API for building web and mobile applications. Check out our top pointers for designing your REST API.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}