Python / GAE Web请求错误处理

时间:2009-08-23 16:35:42

标签: python google-app-engine error-handling design-patterns

我正在使用Python在Google App Engine上开发一个应用程序。

我有一个可以返回各种输出的处理程序(目前是html和json),我正在根据发送给请求处理程序的无效参数测试系统中的明显错误。

然而,我所做的事情感觉很脏(见下文):

class FeedHandler(webapp.RequestHandler):
def get(self):
    app = self.request.get("id")
    name = self.request.get("name") 
    output_type = self.request.get("output", default_value = "html")
    pretty = self.request.get("pretty", default_value = "")


    application = model.Application.GetByKey(app)

    if application is None:
        if output_type == "json":
            self.response.out.write(simplejson.dumps({ "errorCode" : "Application not found."}))
        self.set_status(404)
        return

    category = model.FeedCategory.GetByKey(application, name)

    if category is None:
        if output_type == "json":
            self.response.out.write(simplejson.dumps({ "errorCode" : "Category not found."}))
        self.set_status(404)
        return

我专门处理每种输出类型的情况,并且每个“断言”。

我很想知道如何清理它的建议,模式和例子(我知道尝试和维护我正在做的事情将成为一场噩梦)。

我正在考虑拥有和提高自定义异常并拥有一个能够自动解决如何显示错误消息的装饰器的想法 - 我认为这是一个好主意,但我很乐意得到一些反馈和建议关于人们过去如何做到这一点。

2 个答案:

答案 0 :(得分:9)

这里有几种方便的方法。第一个是自我。error(代码)。默认情况下,此方法只是设置状态代码并清除输出缓冲区,但您可以覆盖它以根据错误结果输出自定义错误页面。

第二种方法是self。handle__exception(例外,debug_mode)。如果任何get / post / etc方法返回未处理的异常,则此方法由webapp基础结构调用。默认情况下,它调用self.error(500)并记录异常(如果启用了调试模式,则将其打印到输出)。您可以覆盖此方法以处理您喜欢的异常。这是一个允许您为各种状态抛出异常的示例:

class StatusCodeException(Exception):
  def __init__(self, code):
    self.status_code = code

class RedirectException(StatusCodeException):
  def __init__(self, location, status=302):
    super(RedirectException, self).__init__(status)
    self.location = location

class ForbiddenException(StatusCodeException):
  def __init__(self):
    super(ForbiddenException, self).__init__(403)

class ExtendedHandler(webapp.RequestHandler):
  def handle_exception(self, exception, debug_mode):
    if isinstance(exception, RedirectException):
      self.redirect(exception.location)
    else:
      self.error(exception.status_code)

答案 1 :(得分:0)

至少,您应该重构重复代码,例如:

if application is None:
    if output_type == "json":
        self.response.out.write(simplejson.dumps({ "errorCode" : "Application not found."}))
        self.set_status(404)
        return

进入辅助方法:

def _Mayerr(self, result, msg):
    if result is None:
        if output_type == 'json':
            self.response.out.write(simplejson.dumps(
                {"errorCode": msg})
        self.set_status(404)
        return True

并将其称为为:

if self._Mayerr(application, "Application not found."):
    return

除此之外,自定义异常(并使用装饰器包装所有处理程序以捕获异常并提供正确的错误消息)是一种出色的体系结构,尽管它比简单的重构更具侵入性(需要更多的代码返工)提到,现在额外的投资可能是值得的,以防止重复和样板错误处理遍布您的应用程序级代码! - )