想在view中设计一个错误处理函数,在view中的不同main函数中使用。 此错误处理程序函数将收集所需的错误信息,将错误记录到系统中,并将这些信息呈现给错误处理程序页面。
view.py 中的代码如下:
def error_manage(request, error_title, error_detail):
error_time = datetime.now()
info_table = {'error_title': error_title,
'error_detail': error_detail,
'error_time ': error_time ,
}
logger.error(str(error_detail))
return render(request,'home/error_manage.html', {'error_title': error_title,
'info_table ': display_table})
def my_page_1(request):
try:
var1 = my_calculation_func()
except Exception as ex:
error_manage(request, "Unexpected Error Happened.", ex)
var2 = my_calculation_func2()
var3 = my_calculation_func3()
return render(request,'home/my_page_1.html', {'var1': var1 ,'var2': var2 ,'var3': var3})
这里的问题是,当var1发生错误时,程序会跳转到error_manage,但不会在这个函数的返回中停止,也不会成功渲染到error_manage.html中。
它稍后会跳出这个函数并继续运行 var2 和 var3,直到遇到 my_page_1() 中的最终返回。
我知道我可以简单地将 error_manage 中的 return 语句放在 Exception 下的 my_page_1 中。 但是这个错误处理程序会在view.py中的许多其他函数中使用,我不想一遍又一遍地重复。
这个问题有没有好的解决办法?谢谢。
答案 0 :(得分:3)
以下是装饰器方法的示例:
class MyError(Exception):
pass
def error_handler(func):
def decorated(*args, **kwargs):
try:
return func(*args, **kwargs)
except MyError as e:
return f"Oh no! {e} happened!"
return decorated
@error_handler
def my_view(request):
if "error" in request:
raise MyError("request was rubbish")
return "Great success!"
for r in ["Fine", "no problem", "An error happened"]:
print(my_view(r))
所以运行这个,我们得到
Great success!
Great success!
Oh no! request was rubbish happened!
所以本质上我们使用装饰器来捕获和处理 MyError 异常,其他异常将不会被处理,而是会像往常一样从视图中冒出来,由 django 的 [默认] 视图错误处理来处理。
答案 1 :(得分:2)
您应该制作一个自定义中间件来处理异常。见Writing your own middleware [Django docs]:
class MyMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_exception(request, exception):
error_time = datetime.now()
info_table = {
'error_detail': exception,
'error_time ': error_time ,
}
logger.error(str(exception))
return render(request,'home/error_manage.html', {'info_table ': display_table})
现在您需要将此中间件添加到设置中的 MIDDLEWARE
列表中:
MIDDLEWARE = [
# Default middlewares
'path.to.MyMiddleware',
]
现在在您看来,您不应该捕获异常并让中间件处理它。
<块引用>注意:通过这种方式,您传递 error_title
的方法将不起作用,但如果您
需要一些自定义:raise Exception("Unexpected Error Happened.") from ex