Python Exceptions – Handling Unknown Exceptions

exceptionspython

When I work with handling exceptions, I notice that I often have to deal with the ones I had no idea about. Especially it is noticeable when I program a method that grabs data from web. An error may occur, for example, due to connection loss, I can handle it. But then another error occurs, a different error with the same cause – connection loss. Okay, added it. Sometimes even yet another occurs. So, the problem is, I am never sure enough if I've handled all the possible errors that may occur due to a certain cause.

At first, I thought about going wildcard and do something like (example in Python):

try:
    #do stuff
except:
    #handle error

But it proved to be a wrong approach soon, cause if I need to handle, say, KeyboardInterrupt, which is raised when a user terminates the program, instead of being handled by a scope I want it to be handled by, it is handled by this wildcard, which is not supposed to have anything to do with it.

So how do I handle exceptions I don't know of but that may possibly occur (or not occur)? Some kind of exceptEverythingBut KeyboardInterrupt:? I doubt many languages have that in their syntax.

EDIT1: a really simplified example:

#!/usr/bin/python3 -u
# -*- coding: utf-8 -*-

try:
    while True:
        try:
            print(1)
        except:
            print(2)
except KeyboardInterrupt:
    print('end')

When I press Ctrl+C, I want it to print 'end' and finish. But instead it prints 2 and continues execution.

If I try this:

#!/usr/bin/python3 -u
# -*- coding: utf-8 -*-

try:
    while True:
        try:
            print(1)
        except KeyboardInterrupt:
            break
        except:
            print(2)
except KeyboardInterrupt:
    print('end')

it finishes, but it skips the outer except and doesn't print 'end'. And that's not what I want. So, the only way I see is to prevent the inner scope from handling KeyboardInterrupt altogether. But it is not possible if there is a except: or except KeyboardInterrupt: in there. So, I need to specify exactly which errors I want to handle in the inner except. But, as I mentioned in the beginning, I don't always know what they can be.

I'm asking this question, because my common way to do it is to just let the program unexpectedly fail several times, read the logs and add handling of errors I didn't know about to new versions; however this could just be a naïve approach, so I want to know how it is done by experienced people.

Best Answer

Just rethrow the exception when you get it:

try:
  #do stuff
except KeyboardInterrupt:
  raise
except:
  #do other stuff

You specify that you get an exception that you know that you want to handle differently than default case, but you don't know how to handle it - so you just pass it, by throwing it again.

Some working example:

#!/usr/bin/python2

if __name__ == "__main__":
    try:
        while True:
            try:
                print(1)
            except KeyboardInterrupt:
                raise
            except:
                print(2)
    except KeyboardInterrupt:
        print('end')

Please note that you shouldn't use except:, as this is a bad practice. except: used in this example is used in sole purpose to make things as simple as possible.

Related Topic