Exception handling is an art which once you master grants you immense powers. I am going to show you some of the ways in which we can handle exceptions.
In basic terminology we are aware of the try/except
structure. The code
that can cause an exception to occur is put in the try
block and
the handling of the exception is implemented in the except
block.
The code in the except
block will only execute if the try
block
runs into an exception.
Here is a simple example:
try:
file = open('test.txt', 'rb')
except IOError as e:
print('An IOError occurred. {}'.format(e.args[-1]))
In the above example we are handling only the IOError exception. What most beginners do not know is that we can handle multiple exceptions.
We can use three methods to handle multiple exceptions. The first one involves putting all the exceptions which are likely to occur in a tuple. Like so:
try:
file = open('test.txt', 'rb')
except (IOError, EOFError) as e:
print("An error occurred. {}".format(e.args[-1]))
Another method is to handle individual exceptions in separate except
blocks. We can have as many except
blocks as we want. Here is an example:
try:
file = open('test.txt', 'rb')
except EOFError as e:
print("An EOF error occurred.")
raise e
except IOError as e:
print("An error occurred.")
raise e
This way if the exception is not handled by the first except
block then
it may be handled by a following block, or none at all. Now the last method involves
trapping ALL exceptions:
try:
file = open('test.txt', 'rb')
except Exception as e:
# Some logging if you want
raise e
This can be helpful when you have no idea about the exceptions that may
be thrown by your program. If you are just looking to catch all execptions,
but don't actually care about what they are, you can even exclude the
Exception as e
part.
Note:: catching all exceptions may have unintended consequences because catching
all exceptions may also catch the ones you want to occur; for example, in
many command-line based programs, pressing control+c will terminate the program,
but if you catch all excepts, the KeyboardInterrupt
will be caught as an
exception, so pressing control+c will NOT terminate the program.
We wrap our main code in the try
clause. After that we wrap some code in
an except
clause which gets executed if an exception occurs in the code
wrapped in the try
clause. In this example we will use a third clause as
well which is the finally
clause. The code which is wrapped in the
finally
clause will run whether or not an exception occurred. It might be used
to perform clean-up after a script. Here is a simple example:
try:
file = open('test.txt', 'rb')
except IOError as e:
print('An IOError occurred. {}'.format(e.args[-1]))
finally:
print("This would be printed whether or not an exception occurred!")
# Output: An IOError occurred. No such file or directory
# This would be printed whether or not an exception occurred!
Often times we might want some code to run if no exception occurs. This
can easily be achieved by using an else
clause. One might ask: why, if
you only want some code to run if no exception occurs, wouldn't you simply
put that code inside the try
? The answer is that then any exceptions in
that code will be caught by the try
, and you might not want that. Most
people don't use it and honestly I have myself not used it widely. Here is an
example:
try:
print('I am sure no exception is going to occur!')
except Exception:
print('exception')
else:
# any code that should only run if no exception occurs in the try,
# but for which exceptions should NOT be caught
print('This would only run if no exception occurs. And an error here '
'would NOT be caught.')
finally:
print('This would be printed in every case.')
# Output: I am sure no exception is going to occur!
# This would only run if no exception occurs. And an error here would NOT be caught
# This would be printed in every case.
The else
clause would only run if no exception occurs and it would run
before the finally
clause.