如何正确处理Python3上的多个连接错误异常?与python-binance包相关

bvk5enib  于 2023-03-31  发布在  Python
关注(0)|答案(2)|浏览(196)

我正在使用python-binance包版本1.0.16(今天的最后一个版本)编写一个小的加密货币跟踪器
我的问题出现在这个过程的某个特定部分,即使用API和密钥通过Client登录到Binance服务器。下面是代码:

from binance.Client import Client

api = input("Paste your API KEY here: ")
secret = input("Now paste your SECRET KEY here: ")

client = Client(api_key=api, api_secret=secret, tld = "com")
  • 注意:只要用户有稳定的互联网连接,不会引发异常,允许跟踪器按预期工作 *

但是,如果用户甚至没有连接到互联网(没有明显注意到它),则在执行上面的代码后会抛出以下异常:

Traceback (most recent call last):

  File "F:\Python\Python310\lib\site-packages\urllib3\connection.py", line 174, in _new_conn
    conn = connection.create_connection(

  File "F:\Python\Python310\lib\site-packages\urllib3\util\connection.py", line 72, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):

  File "F:\Python\Python310\lib\socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):

gaierror: [Errno 11001] getaddrinfo failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "F:\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(

  File "F:\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)

  File "F:\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 1042, in _validate_conn
    conn.connect()

  File "F:\Python\Python310\lib\site-packages\urllib3\connection.py", line 358, in connect
    self.sock = conn = self._new_conn()

  File "F:\Python\Python310\lib\site-packages\urllib3\connection.py", line 186, in _new_conn
    raise NewConnectionError(

NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x0000020B4CEB4A00>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "F:\Python\Python310\lib\site-packages\requests\adapters.py", line 489, in send
    resp = conn.urlopen(

  File "F:\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen
    retries = retries.increment(

  File "F:\Python\Python310\lib\site-packages\urllib3\util\retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))

MaxRetryError: HTTPSConnectionPool(host='api.binance.com', port=443): Max retries exceeded with url: /api/v3/ping (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x0000020B4CEB4A00>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "F:\Python\Python310\lib\site-packages\spyder_kernels\py3compat.py", line 356, in compat_exec
    exec(code, globals, locals)

  File "c:\users\user\.spyder-py3\btcusdt_only-signals.system.py", line 207, in <module>
    client = Client(api_key= api_key, api_secret= secret_key, tld= "com")

  File "F:\Python\Python310\lib\site-packages\binance\client.py", line 300, in __init__
    self.ping()

  File "F:\Python\Python310\lib\site-packages\binance\client.py", line 526, in ping
    return self._get('ping', version=self.PRIVATE_API_VERSION)

  File "F:\Python\Python310\lib\site-packages\binance\client.py", line 371, in _get
    return self._request_api('get', path, signed, version, **kwargs)

  File "F:\Python\Python310\lib\site-packages\binance\client.py", line 334, in _request_api
    return self._request(method, uri, signed, **kwargs)

  File "F:\Python\Python310\lib\site-packages\binance\client.py", line 314, in _request
    self.response = getattr(self.session, method)(uri, **kwargs)

  File "F:\Python\Python310\lib\site-packages\requests\sessions.py", line 600, in get
    return self.request("GET", url, **kwargs)

  File "F:\Python\Python310\lib\site-packages\requests\sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)

  File "F:\Python\Python310\lib\site-packages\requests\sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)

  File "F:\Python\Python310\lib\site-packages\requests\adapters.py", line 565, in send
    raise ConnectionError(e, request=request)

ConnectionError: HTTPSConnectionPool(host='api.binance.com', port=443): Max retries exceeded with url: /api/v3/ping (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x0000020B4CEB4A00>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'))

因此,本质上,有4个异常需要处理:

  • gaierror
  • NewConnectionError
  • MaxRetryError
  • ConnectionError

一开始我尝试了下面基于this approach的代码,因为我认为gaierror总是第一个引发的异常,* 我猜想 * 通过正确处理它,其余的异常将不会引发:

from binance.Client import Client
import socket

api = input("Paste your API KEY here: ")
secret = input("Now paste your SECRET KEY here: ")

while True:
    try: 
        client = Client(api_key= api_key, api_secret= secret_key, tld= "com")
        break
    except socket.gaierror:
        print("You are not connected to the internet, first make sure to be connected before executing this program")
        input("Once done, press Enter key:")

不幸的是,我的方法没有处理任何事情,最终抛出了与上面描述的完全相同的输出,并以相同的顺序引发了相同的异常。
但是,另一个确实有效!:

from binance.Client import Client

api = input("Paste your API KEY here: ")
secret = input("Now paste your SECRET KEY here: ")

while True:
    try: 
        client = Client(api_key= api_key, api_secret= secret_key, tld= "com")
        break
    except Exception:
        print("You are not connected to the internet, first make sure to be connected before executing this program")
        input("Once done, press Enter key:")

所以,伙计们,我来这里是想知道是否有比设置except Exception更好的方法来处理4个异常?你知道,它看起来不太像Good Practices,也不让我知道背后发生了什么,以及如何向用户解释为什么会发生这样的事情,所以你能帮我吗?

6ojccjat

6ojccjat1#

你可以像这样扩展except块:

from binance.Client import Client
import socket
from urllib3.exceptions import NewConnectionError, MaxRetryError, ConnectionError

api = input("Paste your API KEY here: ")
secret = input("Now paste your SECRET KEY here: ")

while True:
    try: 
        client = Client(api_key= api_key, api_secret= secret_key, tld= "com")
        break
    except (socket.gaierror, NewConnectionError, MaxRetryError, ConnectionError) as e:
        print("You are not connected to the internet, first make sure to be connected before executing this program")
        input("Once done, press Enter key:")

except gaierror as ge:
        print("something ge specific")
    except NewConnectionError as nce:
        print("something nce specific")
    # ...

使用后一种方法,您可以独立地处理每个错误。如果您只想过滤出连接错误并在一个批次中处理它们,第一种方法是一个不错的选择。
谢谢大家。

sg3maiej

sg3maiej2#

它对我不起作用,但我让它起作用了。当你的互联网连接出现问题时,它会继续尝试延迟连接。脚本继续工作,没有任何崩溃。有人知道“超时”参数到底会影响什么吗?

import sys
from binance.client import Client
import pandas as pd
import ta
from configparser import ConfigParser
from time import sleep
from binance.exceptions import BinanceAPIException, BinanceRequestException
from requests.exceptions import Timeout, ReadTimeout, ConnectTimeout, RetryError, HTTPError
from requests.exceptions import ConnectionError as CError
import socket
from urllib3.exceptions import NewConnectionError, MaxRetryError, ConnectionError
from pprint import pprint
from tabulate import tabulate

config = ConfigParser()
config.read('config.ini')
api_key = config.get('keys', 'api_key')
api_secret = config.get('keys', 'api_secret')
market = 'BTCUSDT'

while True:
    try:
        print('Trying to connect Binance Server')
        client = Client(api_key, api_secret, {"timeout": 1000}, testnet=True)
        print("Using Binance TestNet Server")
        # dft = get_market_data(market, False)
        sleep(1)
    except (BinanceAPIException, BinanceRequestException) as Binance_Error:
        print('Binance Error Exception')
        # print('Error type is', type(Binance_Error))
        print('Sleep 10 sec')
        sleep(10)
        continue
    except (socket.gaierror, NewConnectionError, MaxRetryError, ConnectionError) as Socket_Error:
        print('Socket Error Exception')
        # print('Error type is', type(Socket_Error))
        print('Sleep 10 sec')
        sleep(10)
        continue
    except (Timeout, ReadTimeout, ConnectTimeout, RetryError, HTTPError, CError) as Conn_Error:
         print('Connection Error Exception')
         # print('Error type is', type(Conn_Error))
         print('Sleep 10 sec')
         sleep(10)
         continue

相关问题