def generate_crash_handler_decorator(error_decorator=None):
def crash_handler(f):<EOL><INDENT>"""<STR_LIT>"""<EOL>@wraps(f)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>data = {}<EOL>t0 = timenow()<EOL>exception_string = '<STR_LIT>'<EOL>try:<EOL><INDENT>res = f(*args, **kwargs)<EOL><DEDENT>except Exception as e:<EOL><INDENT>exception_string = str(e)<EOL>exc_type, exc_value, exc_traceback = sys.exc_info()<EOL>trace = traceback.format_exception(exc_type, exc_value, exc_traceback, <NUM_LIT:30>)<EOL>data['<STR_LIT>'] = trace<EOL>if hasattr(e, '<STR_LIT>'):<EOL><INDENT>res = e.http_reply()<EOL><DEDENT>else:<EOL><INDENT>e = UnhandledServerError(exception_string)<EOL>log.error("<STR_LIT>" % '<STR_LIT:\n>'.join(trace))<EOL>res = e.http_reply()<EOL><DEDENT><DEDENT>t1 = timenow()<EOL>response_type = type(res).__name__<EOL>status_code = <NUM_LIT:200><EOL>is_an_error = <NUM_LIT:0><EOL>error = '<STR_LIT>'<EOL>error_description = '<STR_LIT>'<EOL>error_user_message = '<STR_LIT>'<EOL>error_id = '<STR_LIT>'<EOL>if isinstance(res, Response):<EOL><INDENT>res_data = None<EOL>status_code = str(res.status_code)<EOL>if str(status_code) == '<STR_LIT>':<EOL><INDENT>if res.content_type == '<STR_LIT:application/json>':<EOL><INDENT>s = str(res.data)<EOL>if '<STR_LIT>' in s and '<STR_LIT>' in s and '<STR_LIT>' in s:<EOL><INDENT>res_data = res.get_data()<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>res_data = res.get_data()<EOL><DEDENT>if res_data:<EOL><INDENT>if type(res_data) is bytes:<EOL><INDENT>res_data = res_data.decode("<STR_LIT:utf-8>")<EOL><DEDENT>is_json = True<EOL>try:<EOL><INDENT>j = json.loads(res_data)<EOL><DEDENT>except ValueError as e:<EOL><INDENT>is_json = False<EOL>j = {'<STR_LIT:error>': res_data, '<STR_LIT:status>': status_code}<EOL><DEDENT>status_code = j['<STR_LIT:status>']<EOL>res.status_code = int(status_code)<EOL>if is_json:<EOL><INDENT>if '<STR_LIT>' not in j:<EOL><INDENT>error_id = str(uuid.uuid4())<EOL>j['<STR_LIT>'] = error_id<EOL>res.set_data(json.dumps(j))<EOL><DEDENT>if error_decorator:<EOL><INDENT>res.set_data(json.dumps(error_decorator(j)))<EOL><DEDENT><DEDENT>error = j.get('<STR_LIT:error>', '<STR_LIT>')<EOL>error_description = j.get('<STR_LIT>', res_data)<EOL>if error_description == '<STR_LIT>':<EOL><INDENT>error_description = res_data<EOL><DEDENT>if not exception_string:<EOL><INDENT>exception_string = error_description<EOL><DEDENT>error_user_message = j.get('<STR_LIT>', '<STR_LIT>')<EOL>is_an_error = <NUM_LIT:1><EOL><DEDENT><DEDENT>request_args = []<EOL>if len(args):<EOL><INDENT>request_args.append(args)<EOL><DEDENT>if kwargs:<EOL><INDENT>request_args.append(kwargs)<EOL><DEDENT>data.update({<EOL>'<STR_LIT>': error_id,<EOL>'<STR_LIT:time>': {<EOL>'<STR_LIT:start>': t0.isoformat(),<EOL>'<STR_LIT:end>': t1.isoformat(),<EOL>'<STR_LIT>': (t1.timestamp() - t0.timestamp()) * <NUM_LIT>,<EOL>},<EOL>'<STR_LIT>': {<EOL>'<STR_LIT:type>': response_type,<EOL>'<STR_LIT:status>': str(status_code),<EOL>'<STR_LIT>': is_an_error,<EOL>'<STR_LIT>': error,<EOL>'<STR_LIT>': error_description,<EOL>'<STR_LIT>': error_user_message,<EOL>},<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': pformat(request_args),<EOL>},<EOL>})<EOL>populate_error_report(data)<EOL>fname = function_name(f)<EOL>if data['<STR_LIT>']['<STR_LIT:status>'] and int(data['<STR_LIT>']['<STR_LIT:status>']) >= <NUM_LIT>:<EOL><INDENT>report_error(<EOL>title="<STR_LIT>" % (fname, exception_string),<EOL>data=data,<EOL>is_fatal=True<EOL>)<EOL><DEDENT>log.info("<STR_LIT>")<EOL>log.info("<STR_LIT>")<EOL>log.info("<STR_LIT>")<EOL>return res<EOL><DEDENT>return wrapper<EOL><DEDENT>return crash_handler<EOL>
Return the crash_handler to pass to pymacaron_core, with optional error decoration