Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a unit test for uncaught exception handler

I have a function to catch uncaught exceptions, below. Is there any way to write a unit test that will execute the uncaught_exception_handler() function, but exit the test normally?

import logging

def config_logger():
    # logger setup here

def init_uncaught_exception_logger(logger):
    '''Setup an exception handler to log uncaught exceptions.

    This is typically called once per main executable.
    This function only exists to provide a logger context to the nested function.

    Args:
        logger (Logger): The logger object to log uncaught exceptions with.
    '''
    def uncaught_exception_handler(*exc_args):
        '''Log uncaught exceptions with logger.

        Args:
            exc_args: exception type, value, and traceback
        '''
        print("Triggered uncaught_exception_handler")
        logger.error("uncaught: {}: {}\n{}".format(*exc_args))

    sys.excepthook = uncaught_exception_handler

if __name__ == '__main__':
    LOGGER = config_logger()
    init_uncaught_exception_logger(LOGGER)
    raise Exception("This is an intentional uncaught exception")
like image 915
Quantum Mechanic Avatar asked Sep 05 '25 02:09

Quantum Mechanic


1 Answers

Instead of testing that your function is called for uncaught exceptions, it's probably best to instead test that the excepthook is installed, and that the function does the right thing when you call it manually. That gives you pretty good evidence that the excepthook will behave properly in real usage. You'll want to move your uncaught_exception_handler outside of init_uncaught_exception_logger so your tests can access it more easily.

assert sys.excepthook is uncaught_exception_handler
with your_preferred_output_capture_mechanism:
    try:
        1/0
    except ZeroDivisionError:
        uncaught_exception_handler(*sys.exc_info())
assert_something_about_captured_output()

If you want to actually invoke excepthook through an uncaught exception, then you'll need to launch a subprocess and examine its output. The subprocess module is the way to go for that.

like image 146
user2357112 supports Monica Avatar answered Sep 07 '25 20:09

user2357112 supports Monica