#NEWLINE# @ tornado . gen . coroutine #NEWLINE# def try_hook( task , hookname , loctx , label , argfunc = None ) : #NEWLINE# #INDENT# 'Execute a hook function, if one exists. This catches and logs all\n    errors.\n    The argfunc argument, if present, should be a function that returns a\n    map of (underscorey) local variables. (We handle this as a function\n    so that we can avoid doing it unless necessary. Probably a trivial\n    savings, I know.)\n    ' #NEWLINE# try : #NEWLINE# #INDENT# hook = ( yield two . symbols . find_symbol ( ctx . app , loctx , hookname ) ) #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# hook = None #NEWLINE# #UNINDENT# if ( hook and twcommon . misc . is_typed_dict ( hook , 'code' ) ) : #NEWLINE# #INDENT# ctx = two . evalctx . EvalPropContext ( task , loctx = loctx , level = LEVEL_EXECUTE , forbid = two . evalctx . EVALCAP_MOVE ) #NEWLINE# try : #NEWLINE# #INDENT# if argfunc : #NEWLINE# #INDENT# args = argfunc ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# args = None #NEWLINE# #UNINDENT# ( yield ctx . eval ( hook , evaltype = EVALTYPE_RAW , locals = args ) ) #NEWLINE# #UNINDENT# except Exception as ex : #NEWLINE# #INDENT# task . log . warning ( 'Caught exception (%s): %s' , label , ex , exc_info = task . app . debugstacktraces )