@@ -73,6 +73,16 @@ def get_excepthook_client():
73
73
return client
74
74
75
75
76
+ def get_loop_excepthook_client (loop = None ):
77
+ import asyncio
78
+
79
+ loop = loop or asyncio .get_event_loop ()
80
+ hook = loop .get_exception_handler ()
81
+ client = getattr (hook , 'raven_client' , None )
82
+ if client is not None :
83
+ return client
84
+
85
+
76
86
class ModuleProxyCache (dict ):
77
87
def __missing__ (self , key ):
78
88
module , class_name = key .rsplit ('.' , 1 )
@@ -283,6 +293,55 @@ def install_logging_hook(self):
283
293
from raven .breadcrumbs import install_logging_hook
284
294
install_logging_hook ()
285
295
296
+ def install_asyncio_hook (self , loop = None ):
297
+ import asyncio
298
+
299
+ loop = loop or asyncio .get_event_loop ()
300
+
301
+ try :
302
+ loop_except_handler = loop .get_exception_handler () or type (loop ).default_exception_handler
303
+ except AttributeError :
304
+ # No get_exception_handler before Python 3.5.2
305
+ loop_except_handler = getattr (loop , '_exception_handler' , None ) or type (loop ).default_exception_handler
306
+
307
+ def handle_exception (loop , context ):
308
+ if 'exception' in context :
309
+ exception = context ['exception' ]
310
+ exc_info = type (exception ), exception , exception .__traceback__
311
+ self .captureException (exc_info = exc_info , level = 'exception' ) # asyncio exceptions are non-fatal
312
+ else :
313
+ if 'source_traceback' in context :
314
+ tb = context ['source_traceback' ]
315
+ elif 'handle' in context and getattr (context ['handle' ], '_source_traceback' , None ):
316
+ tb = context ['handle' ]._source_traceback
317
+ elif 'future' in context and getattr (context ['future' ], '_source_traceback' , None ):
318
+ tb = context ['future' ]._source_traceback
319
+ else :
320
+ tb = None
321
+
322
+ if tb :
323
+ frames = []
324
+
325
+ for file_name , lineno , function_name , text in tb :
326
+ frames .append ({
327
+ 'filename' : file_name ,
328
+ 'lineno' : lineno ,
329
+ 'function' : function_name ,
330
+ })
331
+
332
+ if frames :
333
+ data = {'stacktrace' : {'frames' : frames }}
334
+ else :
335
+ data = None
336
+
337
+ message = context .get ('message' , 'Unhandled exception in event loop' )
338
+ self .captureMessage (message , data = data , level = 'exception' )
339
+
340
+ loop_except_handler (loop , context )
341
+
342
+ handle_exception .raven_client = self
343
+ loop .set_exception_handler (handle_exception )
344
+
286
345
def hook_libraries (self , libraries ):
287
346
from raven .breadcrumbs import hook_libraries
288
347
hook_libraries (libraries )
0 commit comments