在调试模式下运行runserver时,如何让Django 1.0将所有错误写入控制台或日志文件?
我已尝试使用具有process_exception函数的中间件类,如此问题的已接受答案中所述:
如何在django站点上记录服务器错误
对于某些异常调用process_exception函数(例如:views.py中的assert(False)),但不会调用process_exception等其他错误,例如ImportErrors(例如:在urs.py中导入thisclassdoesnotexist).我是Django/Python的新手.这是因为运行时和编译时错误之间存在某些区别吗?但是,如果它是编译时错误而不是,那么我希望runserver会抱怨.
我看过Simon Willison关于Django调试的精彩演示(http://simonwillison.net/2008/May/22/debugging/),但我没有看到一个适合我的选项.
如果它是相关的,我正在写一个Facebook应用程序和Facebook屏蔽HTTP 500错误与他们自己的消息,而不是显示Django的信息丰富的500页.所以我需要一种方法将所有类型的错误写入控制台或文件.
编辑:我想我的期望是,如果我在urls.py中导入错误(ImportError)时Django可以返回一个包含大量细节的500错误页面,它应该能够将相同的细节写入控制台或没有文件必须向代码添加任何其他异常处理.我从未见过有关import语句的异常处理.
谢谢,杰夫
这有点极端,但出于调试目的,您可以打开DEBUG_PROPAGATE_EXCEPTIONS
设置.这将允许您设置自己的错误处理.设置所述错误处理的最简单方法是覆盖sys.excepthook.这将终止您的应用程序,但它将起作用.可能有些事情可以让你不要杀死你的应用程序,但这将取决于你正在为此部署的平台.无论如何,永远不要在生产中使用它!
对于生产,您几乎必须具有广泛的错误处理.我使用的一种技术是这样的:
>>> def log_error(func): ... def _call_func(*args, **argd): ... try: ... func(*args, **argd) ... except: ... print "error" #substitute your own error handling ... return _call_func ... >>> @log_error ... def foo(a): ... raise AttributeError ... >>> foo(1) error
如果在视图中使用log_error作为装饰器,它将自动处理其中发生的任何错误.
_
某些异常会调用进程异常函数(例如:views.py中的assert(False)),但_
不会调用进程异常等其他错误(例如:在urs.py中导入thisclassdoesnotexist).我是Django/Python的新手.这是因为运行时和编译时错误之间存在某些区别吗?
在Python中,所有错误都是运行时错误.导致问题的原因是因为在调用视图之前导入模块时会立即发生这些错误.我发布的第一个方法会捕获这些错误以进行调试.你可能能够为生产找到一些东西,但是如果你在生产应用程序中获得ImportErrors(并且你没有进行任何动态导入),我认为你会遇到更糟糕的问题.
像pylint这样的工具可以帮助您消除这些问题.
对于某些异常调用process_exception函数(例如:views.py中的assert(False)),但不会调用process_exception等其他错误,例如ImportErrors(例如:在urs.py中导入thisclassdoesnotexist).我是Django/Python的新手.这是因为运行时和编译时错误之间存在某些区别吗?
不,这只是因为只有在视图中引发异常时才会调用process_exception中间件.
我认为DEBUG_PROPAGATE_EXCEPTIONS(正如Jason Baker首先提到的)就是你在这里所需要的,但是如果你只想将回溯转储到控制台,我认为你不需要做任何额外的事情(即sys.excepthook等).
如果你想对错误执行更复杂的操作(即将其转储到文件或数据库),最简单的方法是get_request_exception信号,Django为任何与请求相关的异常发送信号,无论是否在视图中引发.
django.core.handlers.BaseHandler 的get_response和handle_uncaught_exception方法在这个领域是有益的(和简短的)阅读.
无需向代码添加任何其他异常处理.我从未见过有关import语句的异常处理.
再看一下,你会看到它完成(通常在你想要以某种特定方式处理缺少依赖的情况下).也就是说,如果您不得不在代码中添加额外的try-except块来对全局更改异常进行处理,那当然会非常难看!