flask、django、gin几种异常处理对比分享
python监测异常try:<语句>#运行别的代码except <名字>:<语句>#如果在try部份引发了'name'异常except <名字>,<数据>:<语句>#如果引发了'name'异常,获得附加的数据else:<语句>#如果没有异常发生finaly:<语句>#总会执行try的工作原理
·
python
监测异常
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
finaly:
<语句> #总会执行
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
触发异常
raise Exception()
golang
监测异常
if err != nil {
}
flask
@app.errorhandler(Exception)
def handler_api_exception(exception):
return my_func(exception)
django
viewset(raise)
class UsersGenericMixinAPIView(ListModelMixin,
CreateModelMixin,
RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
GenericViewSet):
queryset = Work.objects.all()
serializer_class =
filter_class =
filter_backends = (DjangoFilterBackend, OrderingFilter)
ordering = ("name",)
pagination_class = None
def create(self, request, *args, **kwargs):
try:
...
except Exception as e:
loging.errinfo(str(e))
from rest_framework.exceptions import APIException
raise APIException("info")
return Response()
# setting 中drf自定义配置,如分页器,鉴权器,异常处理函数等
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.custom_exceptions.custom_exception_handler'
}
# 拦截器中使用了rest_frameworkz中的e exception_handler处理exception,同时可以做一些定义处理
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
response.data['code'] = response.data.get('code') or response.status_code
if response.data.get('msg'):
response.data['msg'] = response.data.get('msg')
elif response.data.get('id'):
response.data['msg'] = response.data.get('id')[0]
elif response.data.get('detail'):
response.data['msg'] = response.data.get('detail')
else:
response.data['msg'] = '参数有误!!'
return response
APIView(not raise)
class UserView(APIView):
def get(req):
try:
...
except:
return Response()
return Response()
gin
panic
使用pannic,然后用一个recover的中间件将程序恢复回来
e.Use(RecoveryMiddleware(DefaultStopExecHandler))
func RecoveryMiddleware(f func(c *gin.Context, err error)) gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
f(c, err.(error))
}
}()
c.Next()
}
}
func StopExec(err error) {
if err == nil {
return
}
panic(err)
}
// 提供一个默认的 recoveryhandler
func DefaultStopExecHandler(c *gin.Context, err error) {
returnfun.ReturnJson(c, 400, 400, err.Error(), "")
}
return
顶层处理错误,直接返回错误对应的状态码
func handleError(c *gin.Context, code int, err error) {
response := map[string]string{}
response["message"] = err.Error()
c.JSON(code, response)
}
疑问
在程序的异常处理中到底是应该使用顶层处理err返回结果,还是应该pannic,raise???
-
如果顶层处理err,结果可控,可以返回用户定义的错误,但是如果涉及多层调用的时候err要逐层传递到可以处理的位置
-
如果raise or pannic 对于程序来说是不友好,返回结果不可控,但是可以错误在哪里就直接处理
更多推荐
已为社区贡献1条内容
所有评论(0)