2014-01-24 29 views
6

鑑於這種簡單的瓶代碼:瓶中間件來捕獲特定類型的異常?

def bar(i): 
    if i%2 == 0: 
     return i 
    raise MyError 

@route('/foo') 
def foo(): 
    try: 
     return bar() 
    except MyError as e: 
     response.status_code = e.pop('status_code') 
     return e 

如何將一個寫瓶中間件所以同樣異常處理是隱式完成的,所以像這樣的代碼可以採用相同的工作上面:

@route('/foo') 
def foo(): 
    return bar() 
+0

難道你根本無法從派生異常bottle.HTTPResponse與異常類型,然後做適當的事情開始或是你的異常的來源,而不是你的Web應用程序的一部分,因此不是已經依賴瓶子? –

+0

從獨立庫中拋出異常;瓶子只是它的一個前端。 – stackoverflowuser95

+1

會[Bottle插件](http://bottlepy.org/docs/dev/plugindev.html)嗎? –

回答

5

你可以做到這一點優雅,配有插件:

def error_translation(func): 
    def wrapper(*args,**kwargs): 
     try: 
      func(*args,**kwargs) 
     except ValueError as e: 
      abort(400, e.message) 
    return wrapper 

app.install(error_translation) 
4

瓶尊重wsgi規範。您可以使用經典的WSGI中間件

from bottle import route, default_app, run, request 

# push an application in the AppStack 
default_app.push() 


@route('/foo') 
def foo(): 
    raise KeyError() 


# error view 
@route('/error') 
def error(): 
    return 'Sorry an error occured %(myapp.error)r' % request.environ 


# get the bottle application. can be a Bottle() instance too 
app = default_app.pop() 
app.catchall = False 


def error_catcher(environ, start_response): 
    # maybe better to fake the start_response callable but this work 
    try: 
     return app.wsgi(environ, start_response) 
    except Exception as e: 
     # redirect to the error view if an exception is raised 
     environ['PATH_INFO'] = '/error' 
     environ['myapp.error'] = e 
     return app.wsgi(environ, start_response) 


# serve the middleware instead of the applicatio 
run(app=error_catcher) 
+0

謝謝,但有沒有一種方法可以顯示錯誤輸出(如JSON)並設置狀態碼;沒有重定向? - 我想''error_catcher'塊中可能有一個lambda ... – stackoverflowuser95

+0

這是一個內部重定向。錯誤視圖可以返回一些json。 error_catcher是一個wsgi應用程序,所以你可以做你想要的或需要的。閱讀有關wsgi應用程序的更多信息:http://webpython.codepoint.net/wsgi_application_interface – gawel

+0

那麼,如何在沒有單獨功能的情況下執行此操作? - 例如:拉姆達方法? – stackoverflowuser95

0

你可以用這個來代替:

from bottle import error, run, route 

@error(500) 
def error_handler_500(error): 
    return json.dumps({"status": "error", "message": str(error.exception)}) 

@route("/") 
def index(): 
    a = {} 
    a['aaa'] 

run()