@@ -73,6 +73,16 @@ def get_excepthook_client():
7373        return  client 
7474
7575
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+ 
7686class  ModuleProxyCache (dict ):
7787    def  __missing__ (self , key ):
7888        module , class_name  =  key .rsplit ('.' , 1 )
@@ -283,6 +293,57 @@ def install_logging_hook(self):
283293        from  raven .breadcrumbs  import  install_logging_hook 
284294        install_logging_hook ()
285295
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 ()
303+         except  AttributeError :
304+             # No get_exception_handler before Python 3.5.2 
305+             loop_except_handler  =  getattr (loop , '_exception_handler' , None )
306+ 
307+         if  not  loop_except_handler :
308+             loop_except_handler  =  type (loop ).default_exception_handler 
309+ 
310+         def  handle_exception (loop , context ):
311+             if  'exception'  in  context :
312+                 exception  =  context ['exception' ]
313+                 exc_info  =  type (exception ), exception , exception .__traceback__ 
314+                 self .captureException (exc_info = exc_info , level = 'exception' )  # asyncio exceptions are non-fatal 
315+             else :
316+                 data  =  {}
317+ 
318+                 if  'source_traceback'  in  context :
319+                     tb  =  context ['source_traceback' ]
320+                 elif  'handle'  in  context  and  getattr (context ['handle' ], '_source_traceback' , None ):
321+                     tb  =  context ['handle' ]._source_traceback 
322+                 elif  'future'  in  context  and  getattr (context ['future' ], '_source_traceback' , None ):
323+                     tb  =  context ['future' ]._source_traceback 
324+                 else :
325+                     tb  =  None 
326+ 
327+                 if  tb :
328+                     frames  =  []
329+ 
330+                     for  file_name , lineno , function_name , text  in  tb :
331+                         frames .append ({
332+                             'filename' : file_name ,
333+                             'lineno' : lineno ,
334+                             'function' : function_name ,
335+                         })
336+ 
337+                     data ['stacktrace' ] =  {'frames' : frames }
338+ 
339+                 message  =  context .get ('message' , 'Unhandled exception in event loop' )
340+                 self .captureMessage (message , data = data , level = 'exception' )
341+ 
342+             loop_except_handler (loop , context )
343+ 
344+         handle_exception .raven_client  =  self 
345+         loop .set_exception_handler (handle_exception )
346+ 
286347    def  hook_libraries (self , libraries ):
287348        from  raven .breadcrumbs  import  hook_libraries 
288349        hook_libraries (libraries )
0 commit comments