下面是最近运行的一个不可靠的Python应用程序的堆栈跟踪的一部分,该应用程序控制另一个用Excel编写的应用程序:
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146788248), None)
显然出了问题。。。但是什么?[1] 这些COM错误代码似乎过于神秘。
如何解码此错误消息?是否有一个表允许我将这个数字错误代码转换成更有意义的代码?
[1]实际上我知道在这种情况下出了什么问题,它试图访问一个没有Name属性的Range对象上的Name prperty。。。不是所有的虫子都这么容易找到!
这样做:
有关在此处消化pythoncom.com_error对象的详细信息:http://docs.activestate.com/activepython/3.2/pywin32/com_error.html
是,请尝试win32api模块:
您可以获取从异常返回的任何代码并将它们传递给FormatMessage。你的例子有两个错误代码。
你没有做错什么。堆栈跟踪中的第一项(数字)是COM对象返回的错误代码。第二项是与错误代码相关联的描述,在本例中为“异常发生”。pywintypes.com_error已经为您调用了等效的win32api.FormatMessage(errCode)。我们马上看第二个号码。
顺便说一下,您可以使用Visual Studio中的“错误查找”实用程序(C:\ Program Files\Microsoft Visual Studio 9.0\Common7\Tools\ErrLook.exe)作为快速启动板来检查COM错误代码。该实用程序还为您调用FormatMessage并显示结果。并不是所有的错误代码都可以使用这个机制,但是很多都可以。那通常是我的第一站。
COM中的错误处理和报告有点混乱。我会给你一些背景资料。
所有COM方法调用都将返回一个名为HRESULT的数字代码,该代码可以指示成功或失败。COM中所有形式的错误报告都建立在这个基础之上。
这些代码通常用十六进制表示,但有时您会看到它们是32位的大数字,就像在堆栈跟踪中一样。对于常见的结果和问题有各种预定义的返回代码,或者对象可以在特殊情况下返回自定义的数字代码。例如,值0(称为S_OK)普遍表示“无错误”,0x80000002是E_OUTOFMEMORY。有时HRESULT代码由对象返回,有时由COM基础结构返回。
COM对象还可以通过实现名为IErrorInfo的接口来选择提供更丰富的错误信息。当一个对象实现IErrorInfo时,它可以提供关于发生了什么的各种详细信息,例如详细的自定义错误消息,甚至描述问题的帮助文件的名称。在VB6和VBA中。
Err
对象允许您访问所有这些信息(Err.Description
,等等)。更为复杂的是,后期绑定的COM对象(使用一种称为COM自动化或IDispatch的机制)添加了一些需要剥离的层来获取信息。Excel通常通过后期绑定进行操作。
现在让我们再看看你的情况。作为第一个数字,您得到的是一个相当通用的错误代码:DISP_E_EXCEPTION。注意:您通常可以通过google找到HRESULT的正式名称,尽管有时您必须使用hex版本才能找到任何有用的名称。
以DISP开头的错误是IDISPATCH错误代码。这个错误松散地意味着“对象抛出了一个COM异常”,更多的信息打包在其他地方(尽管我不太清楚在哪里;我必须查找它)。
根据我对pywintypes.com_error的理解,消息中的最后一个数字是对象在异常期间返回的实际错误代码。这是从VBA的
Err.Number
中得到的实际数字代码。不幸的是,第二个代码-2146788248(0x800A9C68)在为自定义应用程序定义的错误消息保留的范围内(在VBA中:
VbObjectError + someCustomErrorNumber
),因此没有集中的含义。同样的数字对于不同的程序来说意味着完全不同的事情。在这种情况下,我们已经到了死胡同:
Excel(至少对我来说)是臭名昭著的,因为来自自动化的神秘错误代码和导致它们的模糊情况。尤其是对于可以考虑“设计时错误”的错误(“您应该比调用对象中不存在的方法更清楚”)。与“无法读取名称属性”不同,您得到的是“运行时错误“1004”:应用程序定义的或对象定义的错误”(这是我刚刚通过尝试从Excel中的VBA访问范围上的名称属性而得到的)。那不是很有帮助。
该问题不会在Python或它与Excel的接口上路由。Excel本身无法解释发生了什么,甚至VBA也无法解释。
但是,上述一般程序仍然有效。如果以后从Excel中得到一个错误,您可能会得到一个更好的错误消息,您可以用同样的方法跟踪它。
祝你好运!
相关问题 更多 >
编程相关推荐