我正在使用ajax来改善我的Django项目的用户体验。我在这里关注的是如何正确地响应浏览器错误。据我所知,我可以:
对我来说,fisrt方法似乎更正统,因为在Python中,“明确比隐含更好”的哲学确实很重要。但是,由于从第二个中删除了各种异常检查,因此它更清晰,更少碎片,更易读。
我正在使用jQuery来处理ajax请求/响应,这两种方法似乎都有效。我的问题是:
PS。我做了必要的数据验证。请不要为此偏离主题。 :)
答案 0 :(得分:17)
如果您返回状态代码为4xx或5xx的响应,则这是一个错误,将触发jQueries error
处理程序。虽然每次都可以简单地返回状态200并在JSON响应中使用“错误”字段(如dm03514所示),但这有两个原因:
它违反了良好的HTTP惯例。有一个原因为什么定义了大量的错误代码
你不能使用jQuery已经有一个错误处理程序的事实,它允许你将正常行为与错误处理分开。
大多数情况下,错误响应与非错误响应有很大不同所以将这些消息的处理放在一个JS代码中是没有意义的。因此,总而言之,使用状态为200的JSON响应作为正常响应,并返回(适当的!)4xx / 5xx响应以查找错误。这些也可以携带JSON有效负载,因此您的服务器端可以添加有关错误的其他详细信息。
答案 1 :(得分:1)
在我看来:
当我的项目开始时,我总是在文件夹结构的顶部预先添加一个名为errors
的模块,首先,我将编写一个继承自Exception
的基本Exception类,然后写出一些常见的根据我的经验,例如ObjectNotFound
,ValidationError
等异常类。当我认为应该在我的代码中引发异常时,我将使用此模块中的异常,当我发现需要处理新的异常时,我将在其中编写一个新的异常。
然后是如何处理它们的工作。当您使用Django时,很容易通过中间件捕获异常,您可以编写如下内容:
from youproject import errors
# categorize your exceptions
400_ERRORS = (errors.ValidationError, errors.ParametersMissing, )
403_ERRORS = (errors.AuthenticationError, )
404_ERRORS = (errors.ObjectNotFound, errors.ResourceNotExist, )
class ExceptionHandleMiddleware(object):
def process_exception(self, request, e):
# set status_code by category of the exception you caught
if isinstance(e, 400_ERRORS):
status_code = 400
elif isinstance(e, 403_ERRORS):
status_code = 403
elif isinstance(e, 404_ERRORS):
status_code = 404
else:
# if the exception not belone to any one you expected,
# or you just want the response to be 500
status_code = 500
# you can do something like write an error log or send report mail here
logging.error(e)
response_dict = {
'status': 'error',
# the format of error message determined by you base exception class
'msg': str(e)
}
if settings.debug:
# you can even get the traceback infomation when you are in debug mode
response_dict['traceback'] = traceback.format_exc()
# set header and return the response
....
上面的代码是我在项目中如何处理异常处理的摘要,一般来说,它是关于准确的异常控制,正确的异常分类,当然还有“明确优于隐式”的哲学。
=== UPDATE ===
在如何处理ajax中的相应响应时,您可以使用jquery1.5 statusCode
中的新功能:
$.ajax({
statusCode: {
404: function() {
alert('page not found');
}
}
});
来自jquery文档的:
数字HTTP代码和函数的映射 响应有相应的代码。例如,以下将 响应状态为404
时发出警报
答案 2 :(得分:0)
我无法回答这两种方法是否可以接受,但只能告诉你我做了什么。在我看来,我捕获了一些特定/显式错误,例如:
我认为如果您将错误归类为用户必须知道的某些特定错误,然后是其他所有错误,那么您的代码最多会返回2或3个错误路由,恕我直言并非如此糟糕。 我使用JSON返回错误,我的结构通常是这样的:
respons={}
response["error|ok"]
response["msg"]="User not found"
response["type"]=ERROR_TYPE # only applicable for errors
显然这是非常基本的,但希望能给你一个大致的想法。我建议不要让用户看到系统生成的内部服务器错误。即使对于内部应用程序,这也是一种糟糕的用户体验。
希望这有帮助。
答案 3 :(得分:0)
我不会采用您建议的方法。我会建议Sid说的话。你为什么不想编写无错误的代码?
我会尝试在我写的代码中始终解决所有可能的错误和错误。这包括验证用户输入。使用ajax我认为将消息发送回用户很重要。这可以通过json轻松完成。
response_dict = {}
try:
# do action that could cause an error
except ExpectedError as e:
response_dict['success'] = False
response_dict['message'] e.msg # or custom message
return HttpResponse(json.dumps(repsonse_dict))
然后在你的ajax回调中确保响应有效,如果它不警告用户他们做错了什么。不要让他们挂起你正在为他们制作应用程序!
答案 4 :(得分:0)
使用选项1但不完全按照您描述的方式,您应该返回一个带有status_code 200的HttpResponse,在响应内容中指示(使用JSON或某些文本)发生验证错误,然后,当您处理响应时使用JQuery的客户端只需检查响应内容并检测是否存在验证错误。
HttpResponse的JSON字符串示例:
{"errors": "true", "messages": ["Error #1", "Error #2", "etc."]}
选项2不是一个好的做法,因为当服务器抛出一个未捕获的异常时会发生内部服务器错误,程序员通常不知道。
不要使用HTTP状态代码来表示验证错误,这不是它们的目的。