Exception Handling

Our object is to write robust code that can handle erroneous conditions or exceptions when they arise. Python provides a try-except-finally block that allows us to do so. Exceptions are raised in the try block and handled in the except block. The code in the finally block goes through the cleaning up and closing process of the program whether an exception occurred or not.

All Python exceptions inherit from BaseException. The Exception Hierarchy contains many exceptions like - ArithmeticError, RunTimeError, LookupError, SyntaxError, etc. Here is a comprehensive list of exceptions.

The general syntax for using exceptions:

try:
  # body of code where exceptions may occur or be raised
  ...
except :
  # code to handle errors of this type
  ...
except :
  # code to handle errors of this type
  ...
else:
  # if no exception occurred
  ...
finally:
  # cleanup code
  ...
The except blocks act like elifs. Once a match has been found that except block is executed and all subsequent except blocks are skipped. Note that the finally block is optional. The usual practice is to arrange the except starting with the most specific error to the the most general error. The else block is also optional and must follow all the except blocks. This code is executed if the try block does not raise an exception.

There are several ways to handle exceptions:

Exception are raised when a problem occurs. For example, in the function that computes the slope of a line, you will raise an exception if the line is parallel to the y-axis.

if (x1 == x2):
  raise RuntimeError ('line parallel to y axis')
You can also raise an exception implicitly by using the assert statement. The syntax is
assert test [, msg]
This will raise an AssertionError that will be handled in an except block.

You can define your own exception class by inheriting from the Exception class or any one of its subclasses. For example, in its simplest form:

class UserDefinedError (RuntimeError):
  def __init__ (self):
    super().__init__()
The UserDefinedError can now be raised and processed like any other built-in errors. For more information on exception handling read the tutorial on exception handling.

Reading Data on the Web

You can read any file on the web by using the function urlopen in the urllib.request module. You will create a file handler in the following manner:

import urllib.request

infile = urllib.request.urlopen ("http://www.cs.utexas.edu/~mitra/csSpring2014/cs313/assgn/names.txt")
fileContent = infile.read().decode()	
The data read from a given URL is raw data in bytes. The decode() function converts the raw data into a string.

If there is an error accessing the file on the web a URLError is raised. This error includes detailed information in an exception object called HTTPError. This information itself is a file like object and can be read:

try:
  u = urlopen ("http://www.cs.utexas.edu/~mitra/csSpring2014/cs313/assgn/names.txt")
  fileContent = u.read().decode()
except HTTPError as ex:
  err_msg = ex.read()