|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2003-03-27 02:50 UTC] phanto@php.net
[2003-03-27 02:51 UTC] phanto@php.net
[2003-03-27 13:57 UTC] phanto@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 18:00:01 2025 UTC |
If php_COM_invoke receives an error as a result of trying to invoke a COM method via C_TYPEINFO_VT(obj)->Invoke, it assumes that the dispatch failed and tries again using C_DISPATCH_VT(obj)->Invoke. However, if the first Invoke succeeds (i.e. actually call into the object method) but the method raises a COM exception, it returns DISP_E_EXCEPTION. php_COM_invoke will then call the same method again using C_DISPATCH_VT. (In my particular case, the COM method was performing some subsequent phases of a larger DB transaction, encountered a deadlock, then rolled back the DB transaction and reported the event by raising an exception. php_COM_invoke swallowed the exception without report and invoked the method again, which, this time, did not encounter the same deadlock, leaving my code without knowledge that a deadlock had caused some of my DB updates to be rolled back. It took me four days to figure out what in the world was happening.) Here's a diff against COM.c which checks for DISP_E_EXCEPTION as a special case. (This diff is against 4.3.2RC1 but AFAICS this error has existed all along.) diff -r temp/php-4.3.2RC1\ext\com\COM.c php-4.3.2RC1\ext\com\COM.c 128,129c128,130 < hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr); < if (SUCCEEDED(hr)) { --- > if(hr != DISP_E_EXCEPTION) { > hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr); > if (SUCCEEDED(hr)) { 131,137c132,139 < * ITypLib doesn't work < * Release ITypeLib and fall back to IDispatch < */ < < C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); < C_HASTLIB(obj) = FALSE; < C_TYPEINFO(obj) = NULL; --- > * ITypLib doesn't work > * Release ITypeLib and fall back to IDispatch > */ > > C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); > C_HASTLIB(obj) = FALSE; > C_TYPEINFO(obj) = NULL; > }