Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

281
Vistas
¿Cómo determinar si se generó una excepción una vez que está en el bloque finalmente?

¿Es posible saber si hubo una excepción una vez que estás en la finally final? Algo como:

 try: funky code finally: if ???: print('the funky code raised')

Estoy buscando hacer algo como esto más SECO:

 try: funky code except HandleThis: # handle it raised = True except DontHandleThis: raised = True raise else: raised = False finally: logger.info('funky code raised %s', raised)

No me gusta que requiera capturar una excepción, que no tiene la intención de manejar, solo para establecer una bandera.


Dado que algunos comentarios solicitan menos "M" en el MCVE, aquí hay más información sobre el caso de uso. El problema real es sobre la escalada de los niveles de registro.

  • El código funky es de terceros y no se puede cambiar.
  • La excepción de falla y el seguimiento de la pila no contienen ninguna información de diagnóstico útil, por lo que usar logger.exception en un bloque de excepción no es útil aquí.
  • Si aparece el código funky, entonces alguna información que necesito ver ya se ha registrado, en el nivel DEBUG. No manejamos ni podemos manejar el error, pero queremos escalar el registro DEBUG porque la información necesaria está allí.
  • El código funky no sube, la mayor parte del tiempo. No quiero escalar los niveles de registro para el caso general, porque es demasiado detallado.

Por lo tanto, el código se ejecuta en un contexto de captura de registro (que configura controladores personalizados para interceptar registros) y parte de la información de depuración se vuelve a registrar retrospectivamente:

 try: with LogCapture() as log: funky_code() # <-- third party badness finally: # log events are buffered in memory. if there was an exception, # emit everything that was captured at a WARNING level for record in log.captured: if <there was an exception>: log_fn = mylogger.warning else: log_fn = getattr(mylogger, record.levelname.lower()) log_fn(record.msg, record.args)
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Usando un administrador de contexto

Podría usar un administrador de contexto personalizado, por ejemplo:

 class DidWeRaise: __slots__ = ('exception_happened', ) # instances will take less memory def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): # If no exception happened the `exc_type` is None self.exception_happened = exc_type is not None

Y luego usa eso dentro del try :

 try: with DidWeRaise() as error_state: # funky code finally: if error_state.exception_happened: print('the funky code raised')

Todavía es una variable adicional, pero probablemente sea mucho más fácil de reutilizar si desea usarla en varios lugares. Y no es necesario que lo cambie usted mismo.

Usando una variable

En caso de que no desee el administrador de contexto, invertiría la lógica del activador y lo alternaría solo en caso de que no haya ocurrido ninguna excepción. De esa manera, no necesita un caso de except para las excepciones que no desea manejar. El lugar más apropiado sería la cláusula else que se ingresa en caso de que el try no arroje una excepción:

 exception_happened = True try: # funky code except HandleThis: # handle this kind of exception else: exception_happened = False finally: if exception_happened: print('the funky code raised')

Y como ya se señaló, en lugar de tener una variable de "alternar", podría reemplazarla (en este caso) con la función de registro deseada:

 mylog = mylogger.WARNING try: with LogCapture() as log: funky_code() except HandleThis: # handle this kind of exception else: # In case absolutely no exception was thrown in the try we can log on debug level mylog = mylogger.DEBUG finally: for record in log.captured: mylog(record.msg, record.args)

Por supuesto, también funcionaría si lo coloca al final de su try (como sugirieron otras respuestas aquí), pero prefiero la cláusula else porque tiene más significado ("ese código debe ejecutarse solo si no hubo una excepción en el bloque try ") y puede ser más fácil de mantener a largo plazo. Aunque todavía es más para mantener que el administrador de contexto porque la variable se configura y alterna en diferentes lugares.

Usando sys.exc_info (funciona solo para excepciones no controladas)

El último enfoque que quiero mencionar probablemente no sea útil para usted, pero tal vez sea útil para futuros lectores que solo quieran saber si hay una excepción no controlada (una excepción que no se capturó en ningún bloque de except o que se generó dentro de un bloque de except ). En ese caso, puede usar sys.exc_info :

 import sys try: # funky code except HandleThis: pass finally: if sys.exc_info()[0] is not None: # only entered if there's an *unhandled* exception, eg NOT a HandleThis exception print('funky code raised')
over 4 years ago · Santiago Trujillo Denunciar

0

raised = True try: funky code raised = False except HandleThis: # handle it finally: logger.info('funky code raised %s', raised)

Dada la información de fondo adicional agregada a la pregunta sobre la selección de un nivel de registro, esto parece muy fácil de adaptar al caso de uso previsto:

 mylog = WARNING try: funky code mylog = DEBUG except HandleThis: # handle it finally: mylog(...)
over 4 years ago · Santiago Trujillo Denunciar

0

Puede asignar fácilmente su excepción detectada a una variable y usarla en el bloque finalmente, por ejemplo:

 >>> x = 1 >>> error = None >>> try: ... x.foo() ... except Exception as e: ... error = e ... finally: ... if error is not None: ... print(error) ... 'int' object has no attribute 'foo'
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda