4

Pythonを使用してGoogle App Engineでアプリケーションを開発しています。Python/GAE Webリクエストのエラー処理

さまざまな出力(現時点では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 

私は特に、出力タイプごとに例を処理してもおよび、「アサート」あたりにしています。

私は、ここで提案、パターン、例を明確にすることに熱心です(私がやっていることを試して維持するのは悪夢になるだろうと知っています)。

私は、カスタム例外を持ち上げていて、エラーメッセージを表示する方法を自動的に実現するデコレータを持っていると考えています。良いアイデアだと思っていますが、フィードバックや提案過去に人々がこれをどのようにしたかに基づいています。補助方法に

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

答えて

9

ここには便利な方法がいくつかあります。最初は自己です。 error(コード)。デフォルトでは、このメソッドはステータスコードを設定して出力バッファをクリアするだけですが、エラー結果に応じてカスタムエラーページを出力するようにオーバーライドすることができます。

2番目の方法は自己です。 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) 
+0

それを愛してください - handle_exceptionが存在していたということは考えていませんでした...(私がページを早く見ても:)これは助けになると私は確信しています - 私はhandle_exceptionのself.response.out.writeを行うことができます出力json? – Kinlan

+1

handle_exceptionは定期的なリクエスト/レスポンスサイクルの一部なので、そこで何かできることができます。 –

+0

甘い - それは私のコードの終わりをクリアします:) – Kinlan

0

少なくともとして、次のような反復コードをリファクタリングべき

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 

、カスタム例外(例外をキャッチし、適切なエラーメッセージを与えるデコレータで、すべてのハンドラを包む)は優れたアーキテクチャである、それはより侵襲的だけれども、(あなたのコードの多くの手直しが必要です)私が言及した単純なリファクタリングよりも、余分な投資は、今度はアプリケーションレベルのコード全体に広がっている反復的で定型的なエラー処理を防ぐ価値があります! - )

+0

ええ、リファクタが必要です。私はカスタムの例外とデコレータのルートには非常に熱心ですが、ビューをどのように変更する必要があるかもしれません - 現時点ではself.response.out.write()です。私はレンダリングされたビューオブジェクトを返すかもしれないし、デコレータ(または他のいくつかのメソッドがレスポンスをレンダリングする)を持っているかもしれません。 – Kinlan

関連する問題