#159709 - 2006-03-24 04:32 PM
RFC - COM Error Processing
|
Glenn Barnas
KiX Supporter
   
Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
|
Greetings!
A request for thought and discussion on improved handling COM errors. Thanks in advance to Doc for uncovering this by making me miserable for the past 24 hours and to Shawn for helping me realize that I wasn't really nuts!
A common test for errors in COM statements is Code:
If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
I'm going to suggest an alternative process after some rather strange events during the past few days...
The COM environment we use returns extended information known as a "HRESULT". Instead of the normal 16 bits of result data, HRESULT returns 32 bits. The lowest 16 bits represent the error, the next 12 bits represent the facility that generated the information, and the last 4 bits are special status. Two of these bits - 30 & 31 - represent the severity of the returned information. This is illustrated in the table below:
Code:
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +---+-+-+-----------------------+-------------------------------+ |Sev|C|R| Facility | Code | +---+-+-+-----------------------+-------------------------------+ where: Sev - is the severity code 00 - Success 01 - Informational 10 - Warning 11 - Error C - is the Customer code flag R - is a reserved bit Facility - is the facility code Code - is the facility's status code
So, if we think about the KiX code fragment above, a value of 0x00110000 would represent a SUCCESS return from the COMPlus facility (facility ID 17), but would be treated as an error by the KiX statements, and would force an immediate exit. Ironically, it would return zero (success) to the calling code! This makes troubleshooting diffucult to say the least. Worse yet, the early exit would return no data. Imagine how confusing it could be to diagnose a problem where the function exits successfully but yet returns no data!
Because the Facility code is embedded in the result code that is being tested, I'd like to propose that we utilize the following process for evaluating the results of COM calls. This is an example, and I'm sure several of you can golf it down - I purposely wrote it this way so that anyone could understand the logic.
The key to this is that the upper two bits must be 0 to truly have success. It can get just a bit more complicated if you want to exit on failures, but treat informational returns as success. (An example of this is - "The installation completed successfully, but changes will not take effect until the system is restarted.")
Assuming that we will treat informational result codes as success, the change is simple. The high-order bit represents the sign value, so if bit 31 is on (for Warning or Error severity) the @ERROR value will be negative! Thus Code:
If @ERROR < 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
is the only change we need to make to properly handle this type of return code. In this and the remaining examples, only the error processing code that would follow a COM object reference is presented.
If we want to include the Informational events in our error processing, we need to do something different. Code:
If @ERROR & 3221225472 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
3221225472 is the decimal value for 0xc0000000. The logical AND masks all other bits except the two high-order bits. This will now exit if either of the two high-order bits are on.
Finally, if we decide to exit on error, and possibly retry or perform alternate processing for informational events: Code:
; Exit error if high order bit is set If @ERROR < 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf ; Do something special if we have an informational event (1073741824 is 0x40000000) If @ERROR & 1073741824 ; retry, recover, or other code to handle the informational event EndIf
; not error, warning, or info event - exit normally Exit 0
Of course, these same issues apply to VBScript, and any other language that interfaces with COM objects.
Also - recognize that by returning shortened error codes, the calling routine will know that an error occurred, but the @SERROR macro may not display the correct message. Error 39 in Facilty 0 is "Disk Full", but this could mean something entirely different in a different facility! Just something to keep in mind, and may not matter if you don't use @SERROR messages.
Glenn
_________________________
Actually I am a Rocket Scientist!
|
|
Top
|
|
|
|
#159710 - 2006-03-24 05:32 PM
Re: RFC - COM Error Processing
|
Howard Bullock
KiX Supporter
   
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
What COM objects do this? Is this something custom or are these COM objects from Microsoft?
|
|
Top
|
|
|
|
#159712 - 2006-03-24 06:15 PM
Re: RFC - COM Error Processing
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
There are two HEAVILY used macro's (functions) in C++ ... used for testing the return values from COM calls ... one is called SUCCEEDED(hresult) and the other is FAILED(hresult) ... they return TRUE or FALSE depending. SUCCEEDED will return TRUE on successes and informationals ... FAILED will return TRUE on errors and warnings. Loosely translated, they would look like this:
Code:
Function SUCCEEDED($hr)
$SUCCEEDED = $hr >= 0
EndFunction
Function FAILED($hr)
$FAILED = $hr < 0
EndFunction
The code for checking a successfull CreateObject would look like this:
Code:
$xml = CreateObject("microsoft.xmldom")
If FAILED(@ERROR) ?"Failed..." Endif
|
|
Top
|
|
|
|
#159713 - 2006-03-24 07:13 PM
Re: RFC - COM Error Processing
|
Howard Bullock
KiX Supporter
   
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Why have we not seen this issue previously?
|
|
Top
|
|
|
|
#159716 - 2006-03-24 07:42 PM
Re: RFC - COM Error Processing
|
NTDOC
Administrator
   
Registered: 2000-07-28
Posts: 11634
Loc: Space
|
You trying to say 6500 line screen buffer is too much 
Seriously Glenn, I think we should add this to the SUGGESTIONS and have Ruud look at implementing better COM error support. As I'm sure you've noticed we all seem to be utilizing more and more COM code around here and having better support for COM is something we've been asking for.
|
|
Top
|
|
|
|
Moderator: Arend_, Allen, Jochen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 840 anonymous users online.
|
|
|