如何使用CherryPy捕获所有异常?

时间:2013-12-05 09:01:31

标签: python exception-handling cherrypy

我使用CherryPy来运行一个非常简单的Web服务器。它旨在处理GET参数,如果它们是正确的,则用它们做一些事情。

import cherrypy

class MainServer(object):
    def index(self, **params):
        # do things with correct parameters
        if 'a' in params:
            print params['a']

    index.exposed = True

cherrypy.quickstart(MainServer())

例如,

http://127.0.0.1:8080/abcde:

 404 Not Found

The path '/abcde' was not found.

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\cherrypy\_cprequest.py", line 656, in respond
    response.body = self.handler()
  File "C:\Python27\lib\site-packages\cherrypy\lib\encoding.py", line 188, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "C:\Python27\lib\site-packages\cherrypy\_cperror.py", line 386, in __call__
    raise self
NotFound: (404, "The path '/abcde' was not found.")
Powered by CherryPy 3.2.4

我正在尝试捕获此异常并显示空白页面,因为客户端不关心它。具体来说,结果将是一个空体,无论是导致异常的url或查询字符串。

我查看了有关错误处理cherrypy._cperror的文档,但我找不到实际使用它的方法。

编辑:我放弃使用CherryPy并使用BaseHTTPServer找到了一个简单的解决方案(请参阅下面的答案,因为它解决了问题,但没有回答问题...叹息...)

7 个答案:

答案 0 :(得分:3)

CherryPy IS 捕获您的异常。这就是它如何将有效页面返回到具有捕获异常的浏览器。

我建议您仔细阅读所有文档。我意识到这不是最好的文档或组织良好,但如果你至少浏览它,框架将更有意义。它是一个小型框架,但几乎可以满足您对应用程序服务器的所有需求。

import cherrypy


def show_blank_page_on_error():
    """Instead of showing something useful to developers but
    disturbing to clients we will show a blank page.

    """
    cherrypy.response.status = 500

    cherrypy.response.body = ''


class Root():
    """Root of the application"""

    _cp_config = {'request.error_response': show_blank_page_on_error}

    @cherrypy.expose
    def index(self):
        """Root url handler"""

        raise Exception 

有关上述页面文档中的示例,请参阅this以获取进一步参考。

答案 1 :(得分:3)

选择最适合您的选项:Default MethodsCustom Error Handling

我认为你不应该使用BaseHTTPServer。如果您的应用程序非常简单,只需获得一个轻量级框架(例如Flask),即使它可能有点过分,或者保持低级别但仍然在WSGI标准内并使用符合WSGI的服务器。

答案 2 :(得分:2)

您只需使用try/except子句:

try:
    cherrypy.quickstart(MainServer())
except: #catches all errors, including basic python errors
    print("Error!")

这将捕获每一个错误。但是如果你只想抓住cherrypy._cperror

from cherrypy import _cperror

try:
    cherrypy.quickstart(MainServer())
except _cperror.CherryPyException: #catches only CherryPy errors.
    print("CherryPy error!")

希望这有帮助!

答案 3 :(得分:2)

文档似乎以某种方式错过了本节。这是我在从源代码中查找有关自定义错误处理的详细说明时发现的。

自定义错误处理

预期的HTTP响应

“ error_page”配置名称空间可用于为以下内容提供自定义HTML输出: 预期的响应(例如404未找到)。提供一个文件名, 输出将被读取。内容将被插值 使用普通的旧Python的%(状态),%(消息),%(回溯)和%(版本) string formatting

_cp_config = {
    'error_page.404': os.path.join(localDir, "static/index.html")
}

从3.1版开始,您还可以提供一个函数或其他可调用为 error_page条目。它将传递相同的状态,消息,回溯和 插入模板的版本参数

def error_page_402(status, message, traceback, version):
    return "Error %s - Well, I'm very sorry but you haven't paid!" % status
cherrypy.config.update({'error_page.402': error_page_402})

在3.1中,除了编号的错误代码外,您还可以提供 error_page.default处理所有没有自己的error_page的代码 条目。

意外错误

CherryPy还具有通用的错误处理机制:每当出现意外情况时 您的代码中发生错误,它将调用 Request.error_response至 设置响应状态,标题和正文。默认情况下,这是相同的 输出为 HTTPError(500)。如果您想提供 一些其他行为,通常替换为“ request.error_response”。

这是一些示例代码,显示了如何显示自定义错误消息以及 发送包含错误的电子邮件

from cherrypy import _cperror

def handle_error():
    cherrypy.response.status = 500
    cherrypy.response.body = [
        "<html><body>Sorry, an error occurred</body></html>"
    ]
    sendMail('error@domain.com',
             'Error in your web app',
             _cperror.format_exc())

@cherrypy.config(**{'request.error_response': handle_error})
class Root:
    pass

请注意,您必须明确设置 response.body 而不仅仅是返回错误消息。

答案 4 :(得分:0)

虽然这是我搜索樱桃异常处理时的最佳结果之一,但是接受的答案没有完全回答这个问题。以下是针对cherrypy 14.0.0的工作代码

# Implement handler method
def exception_handler(status, message, traceback, version)
    # Your logic goes here 

class MyClass()    

   # Update configurations
   _cp_config = {"error_page.default": exception_handler}

请注意方法签名。如果没有此签名,则不会调用您的方法。以下是方法参数的内容,

  • 状态:HTTP状态和说明
  • 消息:附加到例外的消息
  • traceback :格式化堆栈跟踪
  • 版本:Cherrypy版本

答案 5 :(得分:0)

也许您可以使用cherrypy.tools中的“ before_error_response ”处理程序

@cherrypy.tools.register('before_error_response', priority=90)
def handleexception():
    cherrypy.response.status = 500
    cherrypy.response.body = ''

别忘了启用它:

tools.handleexception.on = True

答案 6 :(得分:-1)

我放弃使用CherryPy并最终使用以下代码,该代码使用标准BaseHTTPServer解决了几行问题:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from urlparse import urlparse, parse_qs

class GetHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        url = urlparse(self.path)
        d = parse_qs(url[4])
        if 'c' in d:
            print d['c'][0]
        self.send_response(200)
        self.end_headers()
        return

server = HTTPServer(('localhost', 8080), GetHandler)
server.serve_forever()