I am developing a cryptocurrency tracker using the python-binance
version library 1.0.16
(latest version as of today)
My problem appears in a specific part of the process which is the login to the Binance server through Client
using the api and secret keys . Here is the code for that:
from binance.Client import Client
api = input("Pega tu API KEY aquí: ")
secret = input("Ahora pega tu SECRET KEY aquí: ")
client = Client(api_key=api, api_secret=secret, tld = "com")
Note: As long as the user has a stable internet connection, no exceptions are returned, allowing the tracker to work as it should.
However, if for some reason the user was not connected to the internet (unbeknownst to him), the following exceptions are returned after executing the above code:
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'))
In short, there are 4 exceptions that need to be handled:
gaierror
NewConnectionError
MaxRetryError
ConnectionError
At first I tried to create an alternative according to this one because I thought that since the exception gaierror
was always the first to be returned, I assumed that by handling it correctly, the rest of the exceptions would not be returned, this is what I did:
from binance.Client import Client
import socket
api = input("Pega tu API KEY aquí: ")
secret = input("Ahora pega tu SECRET KEY aquí: ")
while True:
try:
client = Client(api_key= api_key, api_secret= secret_key, tld= "com")
break
except socket.gaierror:
print("No estás conectado a internet, primero asegúrate de estar conectado antes de ejecutar este programa")
input("Una vez hecho, presiona le tecla Enter:")
However, my alternative didn't handle anything and ended up returning the exact same output described above, with the same exceptions returned in the same order.
But, this other one DID WORK !:
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 Exception:
print("No estás conectado a internet, primero asegúrate de estar conectado antes de ejecutar este programa")
input("Una vez hecho, presiona le tecla Enter:")
So, I came here to find out if there is a better way than just putting except Exception
to handle the 4 returned exceptions? I mean, it doesn't look very good Buenas Prácticas
to me, and it also doesn't let me know exactly what's going on and how I can explain to the user why such a thing is going on, so can you give me a hand?
Good day,
What you can do to know the type of exception that returns you and be able to process it properly is to know its name and the arguments it has.
For example with this code that has not been declared
x
:This will return:
So we can see that the correct exception to process this error would be
NameError
Once you identify the type of exception that appears, you can create messages and/or appropriate actions for each case.
You could also use
logging
and/orpost_mortem
from the librarypdb
to save the messages in alogger
(With log) or review in detail what happened (Withpost_mortem
).