Python 3 handling error TypeError: catching classes that do not inherit from BaseException is not allowed

2

When I run this code:

i=0
while i<5:
    i=i+1;
    try:
        SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
    except client.get_order as e:
        print ("This is an error message!{}".format(i))
#End while

I get the following error: TypeError: catching classes that do not inherit from BaseException is not allowed

I read this question in English stack Exception TypeError warning sometimes shown, sometimes not when using throw method of generator and I also read this: link

With this code I manage to partially solve it, since the iterations continue but I can not capture the error code and print it

i=0
while i<5:
    i=i+1;
    try:
        SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
    except:
        print ("This is an error message!{}".format(i))
#End while

Thank you very much

    
asked by Chuox 24.11.2018 в 04:35
source

2 answers

1

The error occurs to you because in the except clause you must indicate which exception you capture. An exception is a class that inherits (directly or indirectly) from the base class Exception .

Instead you have put client.get_order where python expected the name of the exception, and what you have put is a method of an object, and not a class that inherits Exception .

You have two solutions, the bad and the good.

The bad is to directly capture Exception , like this:

try:
    SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
except Exception as e:
    print ("This is an error message!{}".format(e))

The try block could generate different exceptions, for different reasons. Since whatever exception is generated will inherit from Exception , your except will capture it. But this means that you will treat in the same way all the exceptions that may occur, which is not usually the best. The correct thing would be to have multiple blocks except , one for each possible exception, and handle each one as it corresponds.

So, the good is to capture each possible exception individually:

try:
    SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
except Exception1 as e:
    # Codigo para manejar Exception1
except Exception2 as e:
    # Codigo para manejar Exception2
# etc.

If the exception that occurs is none of those that you had anticipated, it will "rise" to the function that has called yours, and if it does not treat it appropriately, it will continue to rise until it "breaks" the program execution and shown to the user.

It is tempting to add a final block except Exception as e: to capture everything that has not entered through one of the previous blocks, but in that case you would be masking a possible error in your program. The error would occur anyway, and if it is not treated correctly it could influence the results of other parts. It is better to let the program break before unforeseen errors, and then add them in their corresponding except that handles them.

In fact in your case you probably do not know what exceptions your try: block can raise. You should look at the documentation to find out and write your except specific, or not put the try: , let the program break, and examine the error it shows to find out "by the bad" what exception it produced.

Again it is tempting to put a except Exception as e: to capture them all, whatever it is, and so not have to go around figuring out what each possible exception is, but it is not the best solution. You can provisionally use this mechanism, so that instead of breaking the program, show you what excecption was ( print(e) ) and then add the except specific, but it can be dangerous that the program continues running after an exception has occurred handled correctly, that's why it's better not to handle it directly, because that will also show what exception occurred and also stop the program .

Update

After the additional information provided by the user in some comments, I can be more specific in the code example.

Apparently the library is being used python-binance which states a couple of exceptions . If we want to capture those specifically, they need to be declared as they are not standard exceptions that python recognizes in advance. Just import your definition of the appropriate module:

from binance.exceptions import BinanceAPIException, BinanceWithdrawException

BinanceAPIException is an exception a bit particular. Indicates that when invoking an API (remote, I understand) an error has occurred. Instead of generating a different exception for each possible error, this library has chosen to generate a single exception and supply the user, within the field code of the exception, the numerical error code returned by the API. This forces the user to look at the API documentation to find out the meaning of all possible error codes .

Therefore the exception handling code in this particular case could look like this:

try:
    SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
except BinanceAPIException as e:
    print("Excepción en la API.", generar_mensaje(e.code)) 
except BinanceWithdrawException as e:
    print("Ha fallado la retirada de fondos")
except Exception as e:
    # Esto último no debería hacerse, capturar una excepción "comodin"
    # y no tratarla puede llevar a errores
    print("Se ha producido otra excepción no prevista")
    print("Razón:", e)

And then you can create the generar_mensaje(c) function that returns an appropriate string for the numeric code c . For example:

def generar_mensaje(c):
   codigos = {
     -1002: "No autorizado",
     -1003: "Demasiadas peticiones",
     -1007: "Timeout",
     -1015: "Demasiadas nuevas órdenes",
     -1100: "Caracteres ilegales",
     -2013: "La orden no existe",
   }
   msg = codigos.get(c, "[Mensaje no traducido]")
   return "Código: {}. {}".format(c, msg)

Note the use of .get() to get the message with the given code, providing a default value if the code is not found in the dictionary.

    
answered by 24.11.2018 в 11:13
0

you can do it like this:

i=0
while i<5:
    i=i+1;
    try:
        SellSta=client.get_order(symbol=Symb,orderId=SellOrderNum,recvWindow=Delay)
    except as e:
        print (f"This is an error message!{e}")
#End while
    
answered by 24.11.2018 в 05:10