【问题标题】:Bottle middleware to catch exceptions of a certain type?瓶中间件捕获某种类型的异常?
【发布时间】:2014-02-14 23:37:11
【问题描述】:

鉴于这个简单的瓶子代码:

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

【问题讨论】:

  • 您能否简单地不从具有异常类型的 bottle.HTTPResponse 派生您的异常,然后做适当的事情开始,或者您的异常的来源不是您的 Web 应用程序的一部分,因此不依赖于瓶子?
  • 异常是从独立库抛出的;瓶子只是它的一个前端。
  • Bottle plugin 就足够了吗?

标签: python plugins wsgi bottle middleware


【解决方案1】:

您可以使用利用 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)

【讨论】:

  • abort() 是什么? - 是os.abort()的意思吗?
  • @ValK 刚刚编辑以添加更多上下文 - 这是bottle 提供的一个函数,用于通过代码+消息中止请求
  • 感谢您的澄清。
【解决方案2】:

瓶子尊重 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)

【讨论】:

  • 谢谢,但有没有办法可以显示错误输出(作为 JSON)并设置状态码;没有重定向? - 我在想error_catcher 块中可能有一个 lambda...
  • 这是一个内部重定向。并且错误视图可以返回一些 json。 error_catcher 是一个 wsgi 应用程序,所以你可以做你想要/需要的。阅读有关 wsgi 应用程序的更多信息:webpython.codepoint.net/wsgi_application_interface
  • 那么在没有单独函数的情况下我该怎么做呢? - 例如:lambda 方法?
【解决方案3】:

您可以改用这个:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2012-01-16
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 2010-10-08
    相关资源
    最近更新 更多