UnboundLocalError 在使用 requests 进行 API 调用时的 ConnectionError

huangapple go评论60阅读模式
英文:

UnboundLocalError at ConnectionError for API call with requests

问题

我正在尝试编写一个用于处理调用API并返回JSON的函数。以下是我目前的函数代码:

import requests

def get_data(url:str, headers:str, timeout_seconds=5) -> str:
    """Return JSON file from API call."""
    try:
        response = requests.get(
            url, headers=headers, timeout=timeout_seconds
            )
        response.raise_for_status()
    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Unspecified error:", err)
    return response.json()

这段代码在请求成功时工作正常,但当尝试通过断开互联网连接来模拟错误时,我会额外收到以下错误消息。这是我在函数中处理不正确的地方吗?

UnboundLocalError: local variable 'response' referenced before assignment
英文:

I am trying to write myself a function to handle my calls to an API, which return a JSON. This is my function at the moment:

import requests

def get_data(url:str, headers:str, timeout_seconds=5) -> str:
    """Return JSON file from API call."""
    try:
        response = requests.get(
            url, headers=headers, timeout=timeout_seconds
            )
        response.raise_for_status()
    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Unspecified error:", err)
    return response.json()

This works fine when the request is successful, but when trying to simulate an error by disconnecting from the internet, I get this error additonally to the Connection Error. Is this something I'm not handling correctly in my function?

UnboundLocalError: local variable 'response' referenced before assignment

答案1

得分: 1

When the call to requests.get() throws an exception in the line response = requests.get(
url, headers=headers, timeout=timeout_seconds
)

the variable response is never assigned. This is causing the UnboundLocalError when you try to access response.json() as response has no meaning

Here is one possible solution:

import requests

def get_data(url:str, headers:str, timeout_seconds=5) -> str:
    """Return JSON file from API call."""
    response = None
    try:
        response = requests.get(
            url, headers=headers, timeout=timeout_seconds
            )
        response.raise_for_status()
    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Unspecified error:", err)
    if response is None:
        return None # returning {} or raising an exception are also options.
    return response.json()

Depending on how you want the caller to handle this and check for no data, you could return None, an empty dict, or raise a custom Exception indicating a failure to retrieve the data.

英文:

When the call to requests.get() throws an exception in the line response = requests.get(
url, headers=headers, timeout=timeout_seconds
)

the variable response is never assigned. This is causing the UnboundLocalError when you try to access response.json() as response has no meaning

Here is one possible solution:

import requests

def get_data(url:str, headers:str, timeout_seconds=5) -> str:
    """Return JSON file from API call."""
    response = None
    try:
        response = requests.get(
            url, headers=headers, timeout=timeout_seconds
            )
        response.raise_for_status()
    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Unspecified error:", err)
    if response is None:
        return None # returning {} or raising an exception are also options.
    return response.json()

Depending on how you want the caller to handle this and check for no data, you could return None, an empty dict, or raise a custom Exception indicating a failure to retrieve the data.

答案2

得分: 1

Return语句位于try-except块外部,如果发生异常,则响应对象不存在。将return语句放在try块内部。

或者,您可以像这样处理所有请求异常:

import requests
from typing import Optional

def get_data(url: str, headers: str, timeout_seconds: int = 5) -> Optional[str]:
    """从API调用中返回JSON文件。"""
    try:
        response = requests.get(url, headers=headers, timeout=timeout_seconds)
        return response.json()
    except requests.exceptions.RequestException as e:
        print("错误:", e)

请注意,`get_data` 的返回值在发生异常时被设置为 `Optional`。

<details>
<summary>英文:</summary>

Return is located out of try-except block, if exception is occurred, then response object is not exists. Place return inside `try` block.

Or you can handle all requests exceptions like this:

    import requests
    from typing import Optional
    
    
    def get_data(url: str, headers: str, timeout_seconds: int = 5) -&gt; Optional[str]:
        &quot;&quot;&quot;Return JSON file from API call.&quot;&quot;&quot;
        try:
            response = requests.get(url, headers=headers, timeout=timeout_seconds)
            return response.json()
        except requests.exceptions.RequestException as e:
            print(&quot;Error:&quot;, e)

Note, that return value of `get_data` is set to `Optional` in case of exception.

</details>



huangapple
  • 本文由 发表于 2023年5月7日 22:33:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194563.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定