0

I already replaced sys.excepthook by a custom exception handler, which works fine :

import logging;
import sys;

logger = logging.getLogger('my_logger');

# Creating handler
handler_print = logging.StreamHandler();
handler_print.setLevel(logging.DEBUG);
logger.addHandler(handler_print);

# creating custom error handler function
def custom_err_handler(exc_type, exc_value, exc_traceback):
    logger.critical("Custom error handler :", exc_info=(exc_type, exc_value, exc_traceback));

sys.excepthook = custom_err_handler;


integer = 3;
print("Value is" + integer); # Custom exception handler called (TypeError: can only concatenate str (not "int") to str)

My problem is to use this custom handler within a thread :

import threading;

threading.excepthook = custom_err_handler; 

class Test_Class(threading.Thread):
    def run(self):
        integer = 3;
        print("Value is" + integer); # Custom exception handler called

test_class = Test_Class();
test_class.start();

Returns :

Custom error handler : Traceback (most recent call last): File "C:\Program Files\Python3.9\lib\threading.py", line 1214, in invoke_excepthook hook(args) TypeError: custom_err_handler() missing 2 required positional arguments: 'exc_value' and 'exc_traceback'

sys.excepthook and threading.excepthook does not seem to expect the same parameters.

How can I use un custom handler for exception raised both inside and outside threads ?

fdamien12
  • 43
  • 4

1 Answers1

0

I managed to get it working. This helped me : 'sys.excepthook' and threading

As the author said, threading.excepthook receives the arguments as a namedtuple instead of multiple arguments. So, it's necessary to check the type of the first argument to check if the custom handler is called from inside or outside a thread :

import logging;
import sys;
import threading;


logger = logging.getLogger('my_logger');

# Creating handler
handler_print = logging.StreamHandler();
handler_print.setLevel(logging.DEBUG);
logger.addHandler(handler_print);


# creating custom error handler function
def custom_err_handler(arg1, arg2 = None, arg3 = None):
    if type(arg1) is threading.ExceptHookArgs: # Exception returned by threading.excepthook as 1 argument
        exc_type = arg1.exc_type;
        exc_value = arg1.exc_value;
        exc_traceback = arg1.exc_traceback;
        print("Exception caught by threading.excepthook");
    else: # Exception returned by sys.excepthook as 3 separated arguments
        exc_type = arg1;
        exc_value = arg2;
        exc_traceback = arg3;
        print("Exception caught by sys.excepthook");

    logger.critical("Custom error handler :", exc_info=(exc_type, exc_value, exc_traceback));

# Overriding default exceptions handers
sys.excepthook = custom_err_handler;  # remplacement de la fonction
threading.excepthook = custom_err_handler;  # remplacement de la fonction


# Exception raised outside the thread
integer = 3;
print("Value is" + integer); # Custom exception handler called


class Test_Class(threading.Thread):
    def run(self):
        # Exception raised inside the thread
        integer = 3;
        print("Value is" + integer); # Custom exception handler called

test_class = Test_Class();
test_class.start();

With this code, exceptions are caught the same way inside and outside the thread.

fdamien12
  • 43
  • 4