【问题标题】:How to get the exception string from requests.exceptions.RequestException如何从 requests.exceptions.RequestException 获取异常字符串
【发布时间】:2018-03-04 19:10:27
【问题描述】:

我有以下烧瓶代码:

from flask import Flask,request,jsonify
import requests
from werkzeug.exceptions import InternalServerError, NotFound
import sys
import json



app = Flask(__name__)
app.config['SECRET_KEY'] = "Secret!"

class InvalidUsage(Exception):
    status_code = 400

    def __init__(self, message, status_code=None, payload=None):
        Exception.__init__(self)
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv['message'] = self.message
        rv['status_code'] = self.status_code
        return rv

@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

@app.route('/test',methods=["GET","POST"])
def test():
    url = "https://httpbin.org/status/404"
    try:
        response = requests.get(url)
        if response.status_code != 200:
            try:
                response.raise_for_status()
            except requests.exceptions.HTTPError:
                status = response.status_code
                print status
                raise InvalidUsage("An HTTP exception has been raised",status_code=status)
    except requests.exceptions.RequestException as e:
        print e

if __name__ == "__main__":
    app.run(debug=True)

我的问题是如何从 requests.exceptions.RequestException 对象 e 中获取异常字符串(消息)和其他相关参数?

还有什么是记录此类异常的最佳方式。如果出现 HTTPError 异常,我可以参考状态代码。

但 requests.exceptions.RequestException 捕获所有请求异常。那么我如何区分它们以及除了使用打印语句之外记录它们的最佳方法是什么。

非常感谢您的任何回答。

【问题讨论】:

标签: python flask python-requests


【解决方案1】:

RequestExceptionHTTPErrorConnectionErrorTimeoutURLRequiredTooManyRedirects 和其他的基类(整个列表可在请求模块的GitHub page 中找到)。似乎处理每个错误并打印相应信息的最佳方法是从更具体的开始处理它们并以最一般的错误(基类)结束。这已在 StackOverflow topic 的 cmets 中得到广泛阐述。对于您的 test() 方法,这可能是:

@app.route('/test',methods=["GET","POST"])
def test():
    url = "https://httpbin.org/status/404"
    try:
        # some code...
    except requests.exceptions.ConnectionError as ece:
        print("Connection Error:", ece)
    except requests.exceptions.Timeout as et:
        print("Timeout Error:", et)
    except requests.exceptions.RequestException as e:
        print("Some Ambiguous Exception:", e)

这样你可以首先捕捉到继承自RequestException类的更具体的错误。

并考虑打印语句的替代方法 - 我不确定这是否正是您的意思,但您可以使用标准 Python logging in Flasklogging module 本身登录控制台或文件(此处为 Python 3).

【讨论】:

  • 我希望能够从每个异常对象中提取错误消息并将其传递给错误处理程序或打印语句。处理错误后如何提取错误消息?
  • 如何才能从请求中捕获所有错误?如果它是基类,except requests.exceptions.RequestException 不应该从该模块中捕获所有异常吗?为什么那行不通
【解决方案2】:

这实际上不是关于使用requests 库的问题,而是关于如何从异常实例中提取错误字符串的一般 Python 问题。答案相对简单:您可以通过在异常实例上调用 str() 将其转换为字符串。任何正确编写的异常处理程序(在requests 或其他方式中)都将实现__str__() 方法以允许对实例进行str() 调用。示例如下:

import requests

rsp = requests.get('https://httpbin.org/status/404')
try:
    if rsp.status_code >= 400:
        rsp.raise_for_status()
except requests.exceptions.RequestException as e:
    error_str = str(e)
    # log 'error_str' to disk, a database, etc.
    print('The error was:', error_str)

是的,在这个例子中,我们打印它,但是一旦你有了字符串,你就有了额外的选择。无论如何,将其保存到 test.py 会在给定您的测试 URL 的情况下产生以下输出:

$ python3 test.py
The error was: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2018-12-13
    • 1970-01-01
    • 2021-08-26
    • 2013-07-14
    • 2010-11-03
    • 2023-01-27
    • 2015-09-02
    相关资源
    最近更新 更多