Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch these exceptions individually?

I am writing a Python program that interfaces with Quickbooks. When connecting to Quickbooks, depending on the problem, I might get one of two common exceptions:

pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'QBXMLRP2.RequestProcessor.2', 'The QuickBooks company data file is currently open in a mode other than the one specified by your application.', None, 0, -2147220464), None)

pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'QBXMLRP2.RequestProcessor.2', 'Could not start QuickBooks.', None, 0, -2147220472), None)

Catching the generic exception with except Exception as e shows that the type of e is <class 'pywintypes.com_error'>, which cannot be used to catch an exception:

... catch pywintypes.com_error as e:
NameError: global name 'pywintypes' is not defined

So how might I catch these two exceptions in a non-generic manner? Ideally the code would have this layout:

try:
    qb = qbsdk_interface.Qbsdk_Interface(QB_FILE)

except QbWrongModeError as e:
    print('Quickbooks is open in the wrong mode!')

except QbClosedError as e:
    print('Quickbooks is closed!')

except Exception as e:
    print('Something else went wrong!')

Of course, the exceptions QbWrongModeError and QbClosedError do not exist, so what should be there in their place?

like image 509
dotancohen Avatar asked Jul 31 '14 08:07

dotancohen


People also ask

How do you catch specific exceptions?

The order of catch statements is important. Put catch blocks targeted to specific exceptions before a general exception catch block or the compiler might issue an error. The proper catch block is determined by matching the type of the exception to the name of the exception specified in the catch block.

How do you catch multiple exceptions in a single catch?

If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can't change it. The byte code generated by this feature is smaller and reduce code redundancy.

How do you handle multiple exceptions with a single except clause?

You can also handle multiple exceptions using a single except clause by passing these exceptions to the clause as a tuple . except (ZeroDivisionError, ValueError, TypeError): print ( "Something has gone wrong.." ) Finally, you can also leave out the name of the exception after the except keyword.


3 Answers

As soon as I posted I found the way to catch the exception in a non-generic manner in a question that appeared in the Related sidebar. Here is the way to capture these exceptions:

from pywintypes import com_error

except com_error as e:

Note that the differing reasons for the exception cannot be handled individually, so the return code must be examined inside the except clause by comparing the value of e.exceptinfo[5]:

except com_error as e:

    if e.excepinfo[5] == -2147220464:
        print('Please change the Quickbooks mode to Multi-user Mode.')

    elif e.excepinfo[5] == -2147220472:
        print('Please start Quickbooks.')

    else:
        raise e

I had considered marking this question as a dupe, but considering that none of the other related questions handle the situation of distinguishing between the different exceptions thrown under this single type, I leave this one as it addresses this issue and answers it.

like image 68
dotancohen Avatar answered Sep 19 '22 19:09

dotancohen


Now pywintypes.error is BaseException.

There is no need to from pywintypes import com_error.

If you want to catch this exception. You can just catch BaseException

except BaseException as e: # to catch pywintypes.error
    print(e.args)

the exception's format likes this:

(0, 'SetForegroundWindow', 'No error message is available')

So If you want to examine the return code,use e.args[0] instead of e.exceptinfo[5]

like image 33
jizhihaoSAMA Avatar answered Sep 17 '22 19:09

jizhihaoSAMA


Just wanted to add something to @jizhihaoSAMA's answer from @dotancohen's answer for added clarity.

You may want to raise any other errors that you're not expecting when catching a specific BaseException. Otherwise the code will just finish but not do what you're expecting.

except BaseException as e:  # to catch pywintypes.error
    if e.args[0] == -2147352567:
        print(my_str)
    else:
        raise e
like image 41
PyHP3D Avatar answered Sep 18 '22 19:09

PyHP3D