Marcus
Marcus

Reputation: 25

How to handle a custom exception raised inside an exception handler?

If I run the following Python script and assuming that my file read will fail, the IOError handler will raise a custom exception, but I am not sure as to how should I handle the custom exception raised. Can anyone please help?

class CustomIOError(IOError):
  def __init__(self, msg):
    super(CustomIOError, self).__init__()
    self.error_msg = msg

try:
  # Open file to read
  with open(fileName) as f:
    for line in f:
    print line,
except IOError :
  raise CustomIOError('Exception message')

#  except CustomIOError :
#    sys.exit(0)

Also if Python supports polymorphism, why can't I directly handle an exception of base class, with with an exception handler of derived class?

try:
  raise IOError
except CustomIOError:
  pass

This won't work, program execution will terminate after printing a portion of stack trace.

Upvotes: 0

Views: 195

Answers (2)

georg
georg

Reputation: 214959

Once an exception gets caught by an except clause, any subsequent excepts in the same block are ignored, so you can't do that:

try:
   ...
except Something:
   raise MyError
except MyError: <-- won't work!
  ....

You need another try block around the whole thing:

try:

    try:
       ...
    except Something:
       raise MyError

except MyError: <-- will work
   ...

For the second question, it works another way round:

try:
  raise CustomIOError
except IOError: <-- works
  pass

This is because CustomIOError is an IOError, but IOError is not CustomIOError (compare: dog is an animal, but (any) animal is not a dog), so your except doesn't match.

In general, custom exceptions provide a way to wrap generic errors into application-specific ones, so that the high-level code doesn't have to deal with all error details when something goes wrong. For example, you have a function that reads a file and writes the content to a sql database. The code that invokes this function only wants to know if it succeeds or fails, details are irrelevant (although they should be logged for investigation later on). So, the function just throws one exception to indicate that it failed:

# higher-level code

class UserInterface:

     def writeButtonClick:
        try:
            readAndWrite()
        except ReadAndWriteFailure:
            showMessage("Problem! Please try again") 

# lower-level code

class ReadAndWriteFailure(Exception):
    pass

def readAndWrite():
   try:
       fp = open(someFile)
       db = sql.connection()
       for line in fp:
          db.execute(line)
   except IOError:
      log it
      raise ReadAndWriteFailure()
   except SQLError:
      log it
      raise ReadAndWriteFailure()
   etc

Upvotes: 2

amow
amow

Reputation: 2223

  1. expect sub type cant catch a super type error
  2. the exception throws from except part A cant be catch by the except part next to A

So if catch IOError , throw CustomIOError and handle that CustomIOError is what you want. You can use a try...except block outside the IOError block

Upvotes: 0

Related Questions