#64543 - 2002-04-16 11:26 PM
Re: UDF Design
|
New Mexico Mark
Hey THIS is FUN
  
Registered: 2002-01-03
Posts: 223
Loc: Columbia, SC
|
A couple of additional thoughts here:
1. Shawn has a good point about recycling MS error codes, where possible. However, a UDF that uses hundreds or thousands of possible error codes is far exceeding the scope of a function. If you limit (and therefore identify) a subset of MS errors, you might as well make your own system.
2. There are two ways to represent errors. If only one error will ever be returned, a 32-bit integer can represent over billions of distinct errors. However, in most cases, there is less need for this many error codes and more need for one error number that can represent zero, one, or more than one simultaneous errors. In this case, a 32-bit number can represent 32 distinct errors. Of course, there are still billions of possible combinations of errors, but one only need parse the 32 bits and use error handling as necessary from there.
For example, we have a pretty extensive logon script, as it is doing much of the job in lieu of SMS while the USAF is experimenting with brain-dead Tivoli [motto - "We do one-quarter of the job of SMS at only twenty times the cost!"]. First, I set the values of the errors, with the array element number corresponding to the bit number of the error.
code:
; General structure is: ; Bits 0 - 7 General messages and minor change reporting ; Bits 8 - 15 Major change reporting / non-fatal errors ; Bits 16 - 23 Fatal errors and security violations ; Bits 24 - 30 Internal script errors for $intCtr = 0 to ubound($aryMsgCat) $aryMsgCat[$intCtr] = "" next $aryMsgCat[0] = "INF" ; 1 $aryMsgCat[1] = "MND" ; 2 $aryMsgCat[2] = "UCC" ; 4 $aryMsgCat[3] = "SCC" ; 8 $aryMsgCat[4] = "VSF" ; 16 $aryMsgCat[5] = "MIF" ; 32 $aryMsgCat[6] = "RAS" ; 64 $aryMsgCat[7] = "LCF" ; 128 $aryMsgCat[8] = "CDF" ; 256 $aryMsgCat[9] = "NFE" ; 512 $aryMsgCat[10] = "NLA" ; 1024 $aryMsgCat[11] = "NSS" ; 2048 $aryMsgCat[12] = "NSD" ; 4096 $aryMsgCat[16] = "ERR" ; 65536 $aryMsgCat[17] = "SEC" ; 131072 $aryMsgCat[18] = "NOS" ; 262144 for $intCtr = 0 to ubound($aryMsgTxt) $aryMsgTxt[$intCtr] = "" next $aryMsgTxt[0] = "Debugging and status INFormation" $aryMsgTxt[1] = "Mapped Network Drive" $aryMsgTxt[2] = "User Configuration Change" $aryMsgTxt[3] = "System Configuration Change" $aryMsgTxt[4] = "Virus Signature File update" $aryMsgTxt[5] = "MIF File creation or update" $aryMsgTxt[6] = "RAS connection" $aryMsgTxt[7] = "Local Configuration Flag" $aryMsgTxt[8] = "unable to Create Directory or File" $aryMsgTxt[9] = "Non-Fatal Error" $aryMsgTxt[10] = "Not in Local Administrators group" $aryMsgTxt[11] = "Non-Standard Script program or version" $aryMsgTxt[12] = "Non-Standard Domain" $aryMsgTxt[16] = "external or internal ERRor" $aryMsgTxt[17] = "SECurity problem or error" $aryMsgTxt[18] = "Non-Standard Operating system or server"
I echo these values to each user's log to help our Help Desk folks read the codes in the logs:
code:
Write(@CRLF + 'The following is a list of active error codes used in the script.',1) Write('Spaces inserted in acronyms here to prevent false hits in searches.',1) Write('CATEGORY BIT VALUE DESCRIPTION',1) FOR $iCtr = 0 to UBound($aMsgCat) IF $aMsgCat[$iCtr] <> '' $iTmp = Exp(2,$iCtr) $sTmp = SubStr($aMsgCat[$iCtr],1,1) + ' ' + SubStr($aMsgCat[$iCtr],2,1) + ' ' + SubStr($aMsgCat[$iCtr],3,1) + ' ' + SubStr(' ',1,2 - Len($iCtr)) + $iCtr + ' ' + SubStr(' ',1,9 - Len($iTmp)) + $iTmp + ' ' + $aMsgTxt[$iCtr] Write($sTmp,1) ENDIF NEXT
During script execution, I log errors and information. Then, at the end of the script, I do a summary of the error codes set during script execution:
code:
Write('Exit code: ' + $iExCode,1) Write('This can be decoded as follows...',1) FOR $iCtr = 0 to 30 $Exp = Exp(2,$iCtr) IF $iExCode & $Exp Write($aMsgCat[$iCtr] + '- ' + $Exp + ' ' + $aMsgTxt[$iCtr],1) ENDIF NEXT ELSE Write('INF - TGLOGON.KIX completed with no significant actions or errors.',1) ENDIF
Similarly, my UDF's have bitwise error codes. If the UDF is more complex, I might set a single script-level error code by evaluating one or more UDF error codes returned in @error.
Finally, always returning an array in order to include error codes and information seems excessive and cumbersome to me. I liked the comments about VBA vs. the old Excel macro language. VBA is MUCH more powerful... so almost no one uses it.
In this case, we are in a gray area, as most of the people writing KiXtart script are assumed to have some level of proficiency with KiXtart. But I'd still try to apply the following rules to a returned value:
1. Return nothing (since a UDF acts as both a function and a procedure in KiXtart) or a single value wherever possible. 2. Return it in the format expected. (I.e. I would expect Exp(x,y) to return a number, not an array of strings) 3. Keep the default operation of the function as simple as possible. By putting errors in the error value of the function, the user has the option of evaluating that error code or not. Forcing the user to deal with this every time is not necessarily a kindness.
My .02.
Thanks,
New Mexico Mark
|
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 601 anonymous users online.
|
|
|