Search code examples
pythonexceptionthrowraisesystemexit

Python exceptions - catching all exceptions but the one expected


I am working on a simple automation script in Python, which could throw exceptions in various spots. In each of them I would like to log a specific message and exit the program. In order to do that, I raise SystemExit after catching the exception and handling it (performing specific logging operations and such).

In the top-level calling of main, I do the following:

if __name__ == "__main__":
    try:
        main()
    except SystemExit:  # handled exception
        sys.exit(1)
    except:  # any unhandled exception
        logging.error('Unexpected error: ', exc_info=True)
        sys.exit(2)

However, using a bare except is something frowned upon. Is using an "exception tree" where I use a bare except to specify "anything but the exception that I've handled" a nonstandard way? Is there a better way to achieve this? I would still like to log these unhandled exceptions, even if they were not handled.

Edit: SystemExit is raised to note that an exception has been handled - no matter what the exception is in my case, I always want to stop running the scripts as any failure should result in an absolute failure.

The main reason I'm asking this is that PEP8 seems to consider using a bare except as an error, and even though I could use except BaseException, it should be just a syntactic difference. Is one way more standard than the other or is there another standard route of achieving this?


Solution

  • Bare exceptions trap things you do not want to trap, such as GeneratorExit. Do it this way:

    except Exception as details:
        logging.error('Unexpected error: {0}'.format(details))