【问题标题】:Python/GAE web request error handlingPython/GAE Web 请求错误处理
【发布时间】:2009-08-23 16:35:41
【问题描述】:

我正在使用 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

我专门处理每个输出类型以及每个“断言”的案例。

我很想在这里提供有关如何清除它的建议、模式和示例(我知道尝试并保持我正在做的事情将是一场噩梦)。

我正在玩弄拥有和引发自定义异常并拥有一个装饰器的想法,该装饰器将自动计算出如何显示错误消息 - 我认为这是一个好主意,但我很想获得一些基于反馈和建议过去人们是如何做到这一点的。

【问题讨论】:

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


    【解决方案1】:

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

    第二种方法是self.handle__exception(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)
    

    【讨论】:

    • 爱它 - 甚至不知道 handle_exception 甚至存在......(即使我之前看到过这个页面 :) 我很确定这会有所帮助 - 我想我可以做 self.response。在handle_exception中out.write输出json?
    • 是的。 handle_exception 是常规请求-响应周期的一部分,因此您可以在其中做任何您想做的事情。
    【解决方案2】:

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

    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
    

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

    【讨论】:

    • 是的,它肯定需要重构。我非常热衷于自定义异常和装饰器路线,尽管我可能还必须改变我如何处理视图 - 目前它是一个 self.response.out.write()。我可能会返回一个呈现的视图对象并让装饰器(或其他一些方法呈现响应)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多