Обработка ошибок веб-запроса Python / GAE - PullRequest
4 голосов
/ 23 августа 2009

Я разрабатываю приложение на Google App Engine с использованием Python.

У меня есть обработчик, который может возвращать различные выходные данные (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 ]

9 голосов
/ 24 августа 2009

Здесь есть несколько удобных методов. Первый - это self. error (code). По умолчанию этот метод просто устанавливает код состояния и очищает буфер вывода, но вы можете переопределить его для вывода пользовательских страниц ошибок в зависимости от результата ошибки.

Второй метод - self. handle__exception (исключение, debug_mode). Этот метод вызывается инфраструктурой веб-приложения, если какой-либо из ваших методов get / post / etc возвращает необработанное исключение. По умолчанию он вызывает 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)
0 голосов
/ 23 августа 2009

Как минимум, вы должны рефакторинг повторяющегося кода, такого как:

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

Кроме того, пользовательские исключения (и обертывание всех ваших обработчиков декоратором, который перехватывает исключения и выдает правильные сообщения об ошибках) - это отличная архитектура, хотя она более инвазивна (требует больше переделок вашего кода), чем простой рефакторинг, который я просто Как уже упоминалось, дополнительные инвестиции прямо сейчас могут оказаться полезными для предотвращения повторяющихся и типовых ошибок обработки, распространяющихся по всему коду уровня приложения! -)

...