Django REST framework的各种技巧——6.异常处理
2016-02-01 19:22
597 查看
restframework内置了基本的异常处理,然而并不够用
Django REST framework的各种技巧【目录索引】
error_code
给开发看的error_message
给用户看的message
然后在settings.py中加上
通过这样的实现你就可以直接在代码中丢异常了,而前端收到的是一个http code为400的json response
url.py里面加上 handler500 = 'service.views.render_500'
Django REST framework的各种技巧【目录索引】
异常处理应该考虑的事情
异常时为了保持api的一致,应该返回jsonerror_code
给开发看的error_message
给用户看的message
开始怼代码
源码中的异常处理,可见是不符合需求的。def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'detail': exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
实现想要的handler
注意我在handler最后一行注释掉的代码,一定不能抓最后的异常,这样log的信息会没有各种堆栈,非常不全class Error(Exception): def __init__(self, err_code, err_message='Internal Server Error', message=u'服务器异常', status_code=status.HTTP_400_BAD_REQUEST): self.err_code = err_code self.err_message = err_message self.message = message self.status_code = status_code def __unicode__(self): return u'[Error] %d: %s(%d)' % (self.err_code, self.err_message, self.status_code) def getResponse(self): return ErrorResponse(self.err_code, self.err_message, self.message, self.status_code) def ErrorResponse(err_code=errors.SYSTEM_ERROR, err_message='Internal Server Error', message=u'服务器异常', status=status.HTTP_400_BAD_REQUEST, headers=None): err = { 'error_code': err_code, 'error': err_message, 'message': message, } return Response(err, status, headers=headers) def custom_exception_handler(exc, context): if isinstance(exc, Error): set_rollback() return ErrorResponse(exc.err_code, exc.err_message, exc.message, status=exc.status_code) if isinstance(exc, (ForeignObjectRelDeleteError, ModelDontHaveIsActiveFiled)): set_rollback() return ErrorResponse(errors.PermissionDenied, unicode(exc), u'抱歉, 已有其他数据与之关联, 禁止删除', status=status.HTTP_403_FORBIDDEN) if isinstance(exc, (RestPermissionDenied, PermissionDenied)): msg = _('Permission denied.') data = { 'detail': six.text_type(msg) } exc_message = str(exc) if 'CSRF' in exc_message: data['detail'] = exc_message set_rollback() return ErrorResponse(errors.PermissionDenied, data, u'opps, 您没有对应的权限', status=status.HTTP_403_FORBIDDEN) .... log.error(exc) # Note: Unhandled exceptions will raise a 500 error. #return ErrorResponse(errors.SYSTEM_ERROR, 'Internal Server Error', status.HTTP_500_INTERNAL_SERVER_ERROR)
然后在settings.py中加上
'EXCEPTION_HANDLER': 'api.exception_handler.custom_exception_handler',
通过这样的实现你就可以直接在代码中丢异常了,而前端收到的是一个http code为400的json response
@POST('name', validators='required') def create(self, request, name, *args, **kwargs): try: Term.objects.get(name=name, is_active=True) raise Error(errors.Exist, err_message=u'已存在对应的年份', message=u'已存在对应的年份') except Term.DoesNotExist: pass return super(TermsView, self).create(request, *args, **kwargs)
关于上面的500的json方式
使用django的自定义404,500handler的方式解决url.py里面加上 handler500 = 'service.views.render_500'
def render_500(request): if request.is_ajax(): err = { 'error_code': errors.SYSTEM_ERROR, 'error': 'Internal Server Error', 'message': 'Internal Server Error', } return JsonResponse(err, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return redirect('/error/?c=500')
相关文章推荐
- Ruby中的异常处理代码编写示例
- MySQL抛出Incorrect string value异常分析
- 浅谈C#中简单的异常引发与处理操作
- 详解C#编程中异常的创建和引发以及异常处理
- django中使用jquery ajax post数据出现403错误的解决办法(两种方法)
- django使用ajax post数据出现403错误如何解决
- 详解JavaScript中的异常处理方法
- java程序中的延时加载异常及解决方案
- 解析Java异常的栈轨迹及其相关方法
- .NET(C#):Emit创建异常处理的方法
- windows7服务器上weblogic启动失败异常解决方法
- 有关ajax的error与后台的异常问题解决
- 深入探讨JAVA中的异常与错误处理
- windows+apache+mod_python配置django运行环境
- GO语言异常处理机制panic和recover分析
- python Django连接MySQL数据库做增删改查
- django自定义Field实现一个字段存储以逗号分隔的字符串
- 浅谈JAVA 异常对于性能的影响
- 解析C++编程中的bad_cast异常
- C++ 异常处理 catch(...)介绍