es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Las excepciones personalizadas simples no se generan de la misma manera que las integradas.

Tengo un programa con multiproceso – 4 procesos, y dentro de éstos genero múltiples hilos, por lo que también es multihilado. No tengo mucha experiencia en el seguimiento y depuración de estos, pero ahora estoy empezando a hacerlo. Sin embargo, tengo este bloque de código en mi servidor TCP:

Tengo excepciones como esta:

class Error(Exception):
    """Excepción básica"""

class NoDataReceived(Error):
    """Lanzada cuando no hay datos"""

Ahora el código:

try:
    ...
    if True:
        raise ValueError('No se recibieron datos')  #  <--- esto imprimirá
        # raise NoDataReceived('No hay datos') #  <--- cuando uso esto, no imprimirá
except ValueError as err:       # integrada
    print('err')
except NoDataReceived as err:   # personalizada
    print('err')   # ¡NO imprime..?

El problema es que cuando planteo un ValueError, lo imprime, pero cuando planteo un NoDataReceived personalizado, no imprime nada.

Necesito decir que es un programa multihilado y multiprocesado (hilos dentro de un proceso), si corro este pedazo de código en un script simple y de un solo hilo, funciona como debería. No me gusta este comportamiento, antes de construir algo sobre esto, necesito entenderlo mejor. Sé que podría usar sys_traceback, pero realmente quiero hacer que esto funcione como debería, simplemente.

¿Tienes alguna explicación para mí, amigos?

[Python 3.8]

Gracias por tu tiempo, Q.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Es posible que la excepción personalizada NoDataReceived no esté siendo atrapada porque es levantada en un hilo o proceso separado que no está siendo monitoreado por el bloque try-except en el hilo/proceso principal.

    Para asegurarnos de que las excepciones sean atrapadas en todos los hilos y procesos, una posible solución es implementar un manejador de errores global que atrape todas las excepciones no manejadas e imprima su rastreo de pila. Esto se puede hacer registrando el manejador usando la función sys.excepthook al comienzo del programa:

    import sys
    import traceback
    
    def error_handler(exctype, value, tb):
        traceback.print_exception(exctype, value, tb)
    
    sys.excepthook = error_handler
    

    Esto hará que todas las excepciones no manejadas se impriman con sus rastreos de pila, independientemente del hilo o proceso en el que se hayan levantado.

    Alternativamente, si desea atrapar la excepción en el hilo/proceso principal pero no está siendo capturada por el bloque try-except, es posible que la excepción se esté levantando en un método o función separados que se están llamando de manera asíncrona (es decir, con asyncio, concurrent.futures u otras bibliotecas similares). En este caso, es posible que la excepción deba ser atrapada utilizando un mecanismo diferente diseñado para el código asíncrono, como asyncio.create_task() o concurrent.futures.as_completed().

Comments are closed.