Handling all but one exception

Question:

How to handle all but one exception?

try:
    something
except <any Exception except for a NoChildException>:
    # handling

Something like this, except without destroying the original traceback:

try:
    something
except NoChildException:
    raise NoChildException
except Exception:
    # handling
Asked By: Ivan Vulović

||

Answers:

The answer is to simply do a bare raise:

try:
    ...
except NoChildException:
    # optionally, do some stuff here and then ...
    raise
except Exception:
    # handling

This will re-raise the last thrown exception, with original stack trace intact (even if it’s been handled!).

Answered By: Gareth Latty

I’d offer this as an improvement on the accepted answer.

try:
    dosomestuff()
except MySpecialException:
    ttype, value, traceback = sys.exc_info()
    raise ttype, value, traceback
except Exception as e:
    mse = convert_to_myspecialexception_with_local_context(e, context)
    raise mse

This approach improves on the accepted answer by maintaining the original stacktrace when MySpecialException is caught, so when your top-level exception handler logs the exception you’ll get a traceback that points to where the original exception was thrown.

Answered By: Jonathan Blackburn

I found a context in which catching all errors but one is not a bad thing, namely unit testing.

If I have a method:

def my_method():
   try:
      something()
   except IOError, e:
      handle_it()

Then it could plausibly have a unit test that looks like:

def test_my_method():
   try:
      my_module.my_method()
   except IOError, e:
      print "shouldn't see this error message"
      assert False
   except Exception, e:
      print "some other error message"
      assert False
   assert True

Because you have now detected that my_method just threw an unexpected exception.

Answered By: coyot

New to Python … but is not this a viable answer?
I use it and apparently works…. and is linear.

try:
    something
except NoChildException:
    assert True
except Exception:
    # handling

E.g., I use this to get rid of (in certain situation useless) return exception FileExistsError from os.mkdir.

That is my code is:

try:
  os.mkdir(dbFileDir, mode=0o700)
except FileExistsError:
  assert True

and I simply accept as an abort to execution the fact that the dir is not somehow accessible.

Answered By: dario1001

You can do type checking on exceptions! Simply write

try:
    ...
except Exception as e:
    if type(e) == NoChildException:
        raise

It still includes the original stack trace.

Answered By: Thomas Wagenaar