There is probably a better way to do this, but I was able to throw this together in about two minutes, and I’m writing this here so I can easily reference it no matter where I am. I’ve been writing a lot of REST apis using Django lately, and I need a way to save the exceptions and stack traces to the logs while not giving out too much information to the callers. I can’t use the automatic email admins functionality because the servers are locked down and not allowed to send email. Adding try/except’s to the existing functions and new ones feels ugly and painful. So I’m going with the following decorator. This one just passes the exception through – you’ll want to figure out if that is the right thing for you to do.
def wrap_ex(fn): """ Wraps the api function in an exception log. """ def _dec(view_func): def _wrapit(request, *args, **kwargs): try: return view_func(request, *args, **kwargs) except: # log cla, exc, trbk = sys.exc_info() extb = traceback.format_tb(trbk) logging.error(u'An error occurred '+unicode(cla)+u': '+unicode(exc)+ u' tb='+unicode(extb)) raise _wrapit.__doc__ = view_func.__doc__ _wrapit.__dict__ = view_func.__dict__ return _wrapit return _dec(fn)
@wrap_ex @api_login_required def api_1_0_calculate(request): return JsonResponse(...)