是否有必要捕获源自HTTP输入的错误?让它自然失败是不是一个好主意(允许异常冒泡)?
我有一个用于AJAX调用的服务器端接口的Django视图,如下所示:
def some_view(request):
try:
some_int = int(request.POST.get('some_int')) # May raise ValueError or TypeError
except (ValueError, TypeError):
return HttpResponseBadRequest('some_int must be an int')
# ... Code that assumes some_int is an int
return HttpResponse('The normal response')
生产代码中是否可以接受这样的内容?
def some_view(request):
some_int = int(request.POST.get('some_int')) # Ignore ValueError or TypeError raised
# ... Code that assumes some_int is an int
return HttpResponse('normal_response')
当我接受更多参数时,我发现维持如此多的try / except块是很令人沮丧的,这些块大部分是相同的,我最终得到了大量的锅炉板代码。
当然我试着将它重构为一个单独的函数,但由于Django需要返回HttpResponse
,而不是作为异常引发,我不能将它插入到没有try / except块的视图中。此外,转换为int并不是我检查的唯一内容...根据输入也执行了许多业务逻辑健全性检查。例如,我将验证传递的JSON是否为特定格式(即int数组的对象数组等)。
我的观点最终只有70多行代码用于完整性检查和几行实际生成响应的代码。不知何故,我觉得应该有一个更优雅的方式,但我没有找到一个所以我正在考虑放弃所有检查,只是让Django照顾它。 这是个坏主意吗?
如果我没有发现例外情况,我会发现以下潜在问题:
我还应该注意其他问题吗?即使在恢复逻辑方面我无能为力,也不会从用户输入中捕获异常,这是错误的。
答案 0 :(得分:0)
我认为处理此问题的最佳方法是编写自己的middleware,捕获异常并将其转换为您想要的响应。
这可能看起来像这样:
# views.py
def some_view(request):
some_int = int(request.POST.get('some_int'))
# ... Code that assumes some_int is an int
return HttpResponse('normal_response')
# middleware.py
class MyValidationMiddleware(object):
def process_exception(self, request, e):
if isinstance(e, ValueError):
return HttpResponseBadRequest('Input did not validate')
else:
return None # let it bubble up
(由于中间件是站点范围的,您可能希望显式定义自己的输入验证异常,以区别于可能发生的其他类型的异常。)
或者,您可以使用每个视图装饰器执行相同的操作。