瓶中间件能够捕获某种类型的异常吗?

时间:2014-01-24 05:00:34

标签: python plugins wsgi bottle middleware

鉴于这个简单的瓶代码:

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

如何编写Bottle中间件,以便隐式完成相同的异常处理,以便像这样的代码可以与上面的代码相同:

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

3 个答案:

答案 0 :(得分:7)

您可以使用abort

的插件优雅地完成此操作
from bottle import abort

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)

答案 1 :(得分: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)

答案 2 :(得分:1)

您可以改用:

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()