Cuando el reactor retorcido está en funcionamiento y se produce una excepción dentro de un aplazamiento que no se detecta, se imprime "Error no controlado" en el terminal junto con un rastreo y la excepción. ¿Es posible manejar / interceptar estas excepciones (por ejemplo, establecer una devolución de llamada o anular un método)?
EDITAR: Soy consciente de que puedo detectar un error al agregar un error a un diferido. Lo que quiero saber es si hay una manera de interceptar una falla / excepción no manejada que ha atravesado la cadena hasta el reactor.
EDITAR: Básicamente, me pregunto si el reactor retorcido tiene un controlador de errores global o algo a lo que se pueda acceder. Me pregunto porque imprime el rastreo y el error de la falla.
Ejemplo:
Unhandled Error
Traceback (most recent call last):
File "/var/projects/python/server.py", line 359, in run_server
return server.run()
File "/var/projects/python/server.py", line 881, in run
reactor.run()
File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1162, in run
self.mainLoop()
File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1171, in mainLoop
self.runUntilCurrent()
--- <exception caught here> ---
File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 793, in runUntilCurrent
call.func(*call.args, **call.kw)
File "/var/projects/python/server.py", line 524, in monitor
elapsed = time.time() - info.last
exceptions.NameError: global name 'info' is not defined
3 respuestas
Debido a que estos rastreos se escriben usando una llamada a twisted.python.log.deferr()
(en Twisted 10.2 de todos modos), es posible redirigirlos utilizando un observador de registros. Esto es lo más común que se puede hacer con estos rastros de pila. No puedo encontrar ninguna clase base para observadores de registro (sorprendentemente) pero hay un par incorporado:
twisted.python.log.PythonLoggingObserver
- Todo lo que se registra va al Python estándar { {X1}} módulo. (Lo uso en mi aplicación).
twisted.python.log.FileLogObserver
: todo lo que se registra va a un archivo.
Ambos captarán trazas de pila reportadas por el reactor. Todo lo que tiene que hacer es construir el observador de registro (sin argumentos) y luego llamar al método start()
del objeto.
(Nota al margen: también hay una StdioOnnaStick
clase que puede construir y asignar a sys.stdout
o sys.stderr
si lo desea. Luego, cualquier cosa que print
vaya al registro Twisted).
Para realmente, realmente interceptar estas llamadas, para que los rastros de la pila nunca se registren, usted podría:
- Subclase
twisted.internet.SelectReactor
y anular su métodorunUntilCurrent()
. Eso es lo que registra los rastros de la pila. Tendría que estudiar la fuente detwisted.internet.base.ReactorBase
antes de hacer esto. - Después de que haya realizado todas las importaciones
twisted.*
, configuretwisted.python.log.deferr
en una función de su elección, que sea compatible con el prototipodef err(_stuff=None, _why=None, **kw)
.
Respondiendo a tu comentario:
Esencialmente, me pregunto si el reactor retorcido tiene un controlador de error global o algo a lo que se pueda acceder. Me pregunto porque imprime el rastreo y el error del error.
La respuesta es "no de manera adecuada".
Primero, el reactor no tiene nada que ver con los diferidos, en realidad, todo el módulo diferido debe colocarse en el paquete twisted.python
, pero esto aún no se puede hacer debido a algunas dependencias. Volviendo a tu pregunta ...
Excavando en el código retorcido (más precisamente, el twisted.internet.defer
módulo) puede delinear el siguiente flujo de eventos:
- Cuando se llama al método
callback
con un resultado, la instancia diferida comienza a ejecutar sus devoluciones de llamada a través de método_runCallbacks
; - Si una de las devoluciones de llamada arroja una excepción, se envuelve en Falla (línea 542);
- Si la cadena de devolución de llamada se agota y el último resultado fue un error, el resultado actual se asigna a la propiedad failResult de un
DebugInfo
instancia (línea 575); - Si la instancia diferida, y por lo tanto su instancia
DebugInfo
, es basura recolectada y todavía hay una falla activa como resultado, el Se llama al métodoDebugInfo.__del__
y se imprime el rastreo.
Dadas estas premisas, una de las soluciones más simples sería parchear la clase DebugInfo
:
from twisted.internet.defer import DebugInfo
del DebugInfo.__del__ # Hides all errors
Puede agregar un error al diferido; las excepciones no controladas se convierten automáticamente a twisted.python.failure.Failure
.
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.