I'm coding a little cryptocurrency tracker using the python-binance
package version 1.0.16
(the last version as of today)
My problem appears at some specific part of the process which is the login to the Binance server through the Client
using the api and secret keys. Here's the code for that:
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")
Note: As long as the user has an stable internet connection, no exception is raised, allowing the tracker to work as expected
But, if the user were not even connected to the internet (without obviously noticing it), the following exceptions would be thrown after executing the code above:
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'))
So, in essence, there are 4 exceptions that need to be handled:
gaierror
NewConnectionError
MaxRetryError
ConnectionError
At first I tried the following code based on this approach because I thought that as gaierror
was always the very first exception raised, I supposed that by correctly handling it, the rest of the exceptions would not be raised:
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:")
Unfortunately, my approach didn't handle anything and ended up throwing exactly the same output described above, with the same exceptions raised in the same order.
However, this other one DID WORK!:
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:")
So guys, I came here to know if there's a better way than just setting except Exception
to handle the 4 exceptions raised? You know, it doesn't look very Good Practices
to me, and also doesn't let me know exactly what's happening behind and how to explain the user why such thing is happening, so may you help me out here?
You can extend your except blocks like so:
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:")
or
except gaierror as ge:
print("something ge specific")
except NewConnectionError as nce:
print("something nce specific")
# ...
With the latter approach, you can handle each error independently. If you want to just filter out connection errors and deal with them in one batch, the first is a good option.
Thank you.