New users of this package may find themselves deeply confused when encountering a COMError.
COMError is an exception defined in the ctypes internal implementation, _ctypes, and is part of the Python standard library. However, it remained undocumented for many years. To address this, I opened an issue and submitted a pull request to add documentation for this error to the official Python documentation.
Another problem with COMError is that most COM references typically represent error codes as signed 32-bit hexadecimal values, like the ones below, while the error code assigned to its hresult attribute is an int, making them less 'googlable'.
Additionally, converting between signed 32-bit hexadecimal strings and integer values requires some extra effort.
For instance, when I was less familiar with HRESULT, I mistakenly tried to derive the integer value for E_NOINTERFACE using int("0x80004002", 16).
To handle these conversions properly, a utility function like the following is necessary:
def signed32bithex_to_int(value: str, /) -> int:
"""
Examples:
>>> from comtypes import hresult as hr
>>> signed32bithex_to_int('0x00000000') == hr.S_OK
True
>>> signed32bithex_to_int('0x00000001') == hr.S_FALSE
True
>>> signed32bithex_to_int('0x8000FFFF') == hr.E_UNEXPECTED
True
"""
val = int(value, 16)
if val < 0x80000000:
return val
return val - 0x100000000
def int_to_signed32bithex(value: int, /) -> str:
"""
Examples:
>>> import comtypes.hresult as hr
>>> int_to_signed32bithex(hr.S_OK)
'0x00000000'
>>> int_to_signed32bithex(hr.S_FALSE)
'0x00000001'
>>> int_to_signed32bithex(hr.E_UNEXPECTED)
'0x8000FFFF'
>>> from comtypes import CoCreateInstance
>>> from comtypes import shelllink, automation
>>> CLSID_ShellLink = shelllink.ShellLink().IPersist_GetClassID()
>>> p = CoCreateInstance(CLSID_ShellLink)
>>> p.QueryInterface(shelllink.IShellLinkA) # doctest: +ELLIPSIS
<POINTER(IShellLinkA) ptr=0x... at ...>
>>> p.QueryInterface(automation.IDispatch) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
_ctypes.COMError: (-2147467262, ..., (None, None, None, 0, None))
>>> int_to_signed32bithex(-2147467262) # E_NOINTERFACE
'0x80004002'
"""
# it is simpler than using `hex(value & 0xFFFFFFFF)`
return f"0x{value & 0xFFFFFFFF:08X}"
For example, let’s consider the case where you encounter an COMError: (-2146233083, ..., ...).
Searching for -2146233083 alone will primarily return information about COR_E_TIMEOUT, which is related to .NET.
However, searching for "0x80131505", which can be derived using int_to_signed32bithex(-2146233083), makes it easier to find information about UIA_E_TIMEOUT, which is related to UIAutomation.
I am considering adding such a function to comtypes/hresult.py with appropriate docstrings.
Doing so will likely reduce the number of inquiries related to error handling in the future, preventing burnout among the community and maintainers.
New users of this package may find themselves deeply confused when encountering a
COMError.COMErroris an exception defined in thectypesinternal implementation,_ctypes, and is part of the Python standard library. However, it remained undocumented for many years. To address this, I opened an issue and submitted a pull request to add documentation for this error to the official Python documentation.Another problem with
COMErroris that most COM references typically represent error codes as signed 32-bit hexadecimal values, like the ones below, while the error code assigned to itshresultattribute is anint, making them less 'googlable'.Additionally, converting between signed 32-bit hexadecimal strings and integer values requires some extra effort.
For instance, when I was less familiar with HRESULT, I mistakenly tried to derive the integer value for
E_NOINTERFACEusingint("0x80004002", 16).To handle these conversions properly, a utility function like the following is necessary:
For example, let’s consider the case where you encounter an
COMError: (-2146233083, ..., ...).Searching for
-2146233083alone will primarily return information aboutCOR_E_TIMEOUT, which is related to .NET.However, searching for
"0x80131505", which can be derived usingint_to_signed32bithex(-2146233083), makes it easier to find information aboutUIA_E_TIMEOUT, which is related to UIAutomation.I am considering adding such a function to
comtypes/hresult.pywith appropriate docstrings.Doing so will likely reduce the number of inquiries related to error handling in the future, preventing burnout among the community and maintainers.