Page 1 of 1 1
Topic Options
#80091 - 2001-05-15 11:34 AM Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
I'd like to be able to set @ERROR and @SERROR in UDFs to indicate error conditions.

------------------
Richard Howarth

Top
#80092 - 2001-05-16 12:19 AM Re: Set @ERROR and @SERROR
Anonymous
Unregistered


Yes please, it would have great value during testing and debugging.
Top
#80093 - 2001-05-16 12:51 AM Re: Set @ERROR and @SERROR
cj Offline
MM club member
*****

Registered: 2000-04-06
Posts: 1102
Loc: Brisbane, Australia
You can already with the EXIT command.

code:

EXIT
Type
Command


Action Exits the current KiXtart script, or, if used at the topmost level, exits KiXtart.


Syntax EXIT [code]


Parameters code
Optional numeric that defines the error level or exit code to be returned to the calling object.
This is accessed as @ERROR in KiXtart or %errorlevel% in a batch file.


in a UDF:

code:

break on
cls


; using cj's version of the Exponential function, get 23 squared
;and return with an error level of 100
exp2(23, 2) ? ; returns 529
@error ? ; returns 100


Function exp2($base, $power)
$Exp2=1
for $i=1 to $power
$Exp2=$Exp2*$base
next
exit 100 ; set @error to 100 and exit this function
EndFunction


cj

------------------
cj's scripts page
cj's User Guide - 14 May 2001

chrismat@ozemail.com.au


 


[This message has been edited by cj (edited 15 May 2001).]

Top
#80094 - 2001-05-15 01:41 PM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Excellent! Halfway there.

Ruud, can you confirm that this is intended to work by design rather than accident

If so the manual needs an update to clarify the action as it currently states the exit "Exits the current KiXtart script", which it doesn't in the case of an exit in a UDF.

We're still stuck with the standard error strings when calling the @SERROR macro though. How about a user defined error message number (65535 maybe?), and change the exit command to accept an arbitrary error message so you could do:

code:
 exit 65535,"Fatal error in UDF"

I've just found in testing that a "RETURN" resets @ERROR, so if you have nested functions you need to:

code:
FUNCTION MyFunction()
$Return=MyOtherFunction(Foo)
if @ERROR exit @ERROR endif
...
return
ENDFUNCTION

------------------
Richard Howarth

[This message has been edited by rhowarth (edited 15 May 2001).]

Top
#80095 - 2001-05-15 03:05 PM Re: Set @ERROR and @SERROR
Shawn Administrator Offline
Administrator
*****

Registered: 1999-08-13
Posts: 8611
yes - being able to set and clear @ERROR would be a very good thing - especially inside UDF's !

Shawn.

Top
#80096 - 2001-05-15 06:10 PM Re: Set @ERROR and @SERROR
cj Offline
MM club member
*****

Registered: 2000-04-06
Posts: 1102
Loc: Brisbane, Australia
If you want to return an error message, just:

$error="it broke!"

etc

set $error="" at the beginning of the UDF if you want to default to working etc...


Top
#80097 - 2001-05-16 09:52 AM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Yes of course I could do it that way, but that defeats the purpose of the original suggestion.

I don't want to introduce new semantics and methods of error reporting when there is something there which already works.

As more and more UDFs collect together as libraries you want to be able to use them in the same way as you would Kix functions, and that means using @ERROR and @SERROR for errors.

Finally (I do go on a bit) I want to be able to distribute UDF's as black box function libraries i.e. you put data in and get results out but whatever goes on inside is hidden and has no other effect on the rest of the script.

I don't want to be creating functions that leave people with fist sized holes in their monitors because their scripts are myseriously failing because I'm changing the content of their global variables in my UDF.

------------------
Richard Howarth

Top
#80098 - 2001-05-16 11:43 AM Re: Set @ERROR and @SERROR
cj Offline
MM club member
*****

Registered: 2000-04-06
Posts: 1102
Loc: Brisbane, Australia
R, IC... AFAIK, although the manual doesn't make this clear and I have yet to test this fully, but I have accidently found this to be the case sometimes: EXIT will exit from the current loop (if...endif, do...until, function...endfunction etc). If so, this is great!

If this is the case (or if it is made the case) then you basically have an ExitIF/ExitSelect/ExitFunction etc statement (something I would like) with the added bonus of being able to set @error.

As for @serror, that is a system thing and I do not believe you should be allowed to faff with it. I personlly use @errors that do not have a system definition, like 1000. You can then create a UDF (called SError) that returns a set of strings for @error=1000, 1001, etc...


I have already suggested that EXIT be improved to do the above idea of exiting the current loop and QUIT be improved to actually exit ALL scripts immediately.

cj

Top
#80099 - 2001-05-17 12:25 AM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Agreed we need the official word on the action of "exit" - if we are taking advantage of an unintentional feature it may well vanish in new versions.

As regards the error number, negative values work fine for @ERROR and you won't accidentally hit a valid system error number (like 1001 ). I didn't suggest negative values originally, as I wasn't at all sure how they'd affect ERRORLEVEL for batch file processing. As @SERROR is a macro call, it shouldn't be at all difficult to trap negative values of @ERROR and return a user defined string. Only one error string needs to be kept as there is only one @ERROR in effect at any time.

I propose then:

1) "exit" should have a second optional parameter which sets a user defined error message.
2) If @ERROR < 0 the content of the user defined error message is returned. If @ERROR >=0 it uses a system call to retrieve the string as it does now.

Of course this pre-supposes that "exit" is working as it should now.

------------------
Richard Howarth

Top
#80100 - 2001-05-16 01:53 PM Re: Set @ERROR and @SERROR
Anonymous
Unregistered


CJ,
In the kind of situation I'm thinking of the EXIT command isn't applicable. When testing I currently need to change the @error to a variable (obviously $error is the normal choice) so that it can be set and cleared as desired. This is mainly so that all logical paths through the script can be properly tested. In essence, I'm forcing error conditions to ensure the error handling does exactly what I want. The use of variables in place of macros does work but is not an ideal arrangement.

Ok, I know this isn't quite in line with the original suggestion of setting the values within UDFs but the idea is still a great one and I think we should be allowed to set the values at will.

[This message has been edited by Fuse (edited 16 May 2001).]

Top
#80101 - 2001-05-16 02:38 PM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Fuse,
You can get the effect you desire by using a UDF to set the error. I used this to print out all the available text error message:
code:
$=redirectoutput("errors.txt")

for $i = 0 to 99999
SetError($i)
if "@SERROR" = ""
if $blank else $blank=$i endif
else
if $blank
? " $blank to " $i-1 " have no message" ? ?
$Blank=0
endif
"@ERROR: @SERROR" ?
endif
next
if $blank
? " $blank to " $i " have no message" ? ?
endif
$=redirectoutput("")

return

function SetError($i)
exit $i
endfunction


You could then do something like this in your code:

code:

; Initialisation area
$ERROR_SUCCESS=0
$ERROR_FILE_NOT_FOUND=2
$ERROR_ACCESS_DENIED=5

$DEBUG=1
$ERRORCHECK=2
$PRODUCTION=0

; Set CODE_STATE to indicate the current state of your code
$CODE_STATE=$DEBUG | $ERRORCHECK

; Initialise @ERROR to OK.
SetError($ERROR_SUCCESS)

...

md "c:\foo\bar"
if $CODE_STATE & $ERRORCHECK SetError($ERROR_ACCESS_DENIED) endif
if @ERROR
"Error @ERROR: @SERROR encountered making directory" ?
if ($CODE_STATE & DEBUG) AND ($CODE_STATE & $ERRORCHECK)
"DEBUG: Forced errors are ON"
endif
endif

return

FUNCTION SetError($ErrorNumber)
exit $ErrorNumber
ENDFUNCTION


------------------
Richard Howarth

Top
#80102 - 2001-05-17 03:53 PM Re: Set @ERROR and @SERROR
Anonymous
Unregistered


Richard,
I can't argue with the results but it's not quite what I'd like to do. Given a pretty straightforward bit of script in which the @error macro is used I'd simply like to be able to add a line something like @error=<some value>, so that I can easily check the actual program flow when specific (or any) error codes are produced by the preceeding function or command. I know it's not a big thing but it's something which would be used so often that it's worth requesting.

Top
#80103 - 2001-05-17 04:07 PM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Ok, I over did the sample script a bit - I just can't help showing off

You only need to include the function, so put this (very short) function in your script somewhere:

code:
FUNCTION SetError($ErrorNumber) exit $ErrorNumber ENDFUNCTION

Then whenever you want to do the check, rather than
@ERROR=<some value>
you'd put
SetError(<some value> )

------------------
Richard Howarth

Top
#80104 - 2001-05-17 04:47 PM Re: Set @ERROR and @SERROR
Bryce Offline
KiX Supporter
*****

Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
nice work!

------------------
kix.isorg.net

Top
#80105 - 2001-05-18 01:41 AM Re: Set @ERROR and @SERROR
kholm Offline
Korg Regular
*****

Registered: 2000-06-19
Posts: 714
Loc: Randers, Denmark
After doing some testing on the posts in this topic, i have come up wiht this:

I hope this will inspire to more ideas in the possibilities of returncodes from UDF's whitout disturbing Ruud.

You don't need a separate function to set @Error, Exit @Error in UDF's works just fine.

As for the setting of @SError, look in the following example, where i picked one of the win32 error codes from
the manual to descripe the error. Of course it would be nice to be able to make your own text for @SError, but
this is my suggestion:

You should be able to find an appropriate error/description from the 500+ decriptions in the manual,
Appendix B: Win32 Error codes.

In this example I use:
Exit 6 ; @SError = ERROR_INVALID_HANDLE
to describe why the UDF ReadSection() didn't work (All available handles (1 - 10) was allready used by Open().
and
Exit 87 ; ERROR_INVALID_PARAMETER
to describe that the UDF ReadSection() was called wiht an invalid argument.

Observe: Even if the the UDF ReadSection() is places inside the build in function Split(), the error is
stil retrieved.
(This is a very nice feature)
Another observation: Don't use @Error in your UDF to check for errors, use $RC as in my example, because calls to
@Error tends to reset @Error.

To test the script on WinNT/2000 you have to copy the file MSPrint.inf from a Win9x workstation, or choose another
ini-like file.

And now the code:

code:
Break On

; Show section. This is the valid version of the call
$File = %WINDIR% + "\Inf\MSPrint.inf"
$Section = "Uni"
ShowSection($File, $Section)
?

; Invalid filename
$File = %WINDIR% + "\Inf\WRONG.INF"
$Section = "Uni"
ShowSection($File, $Section)
?

; Invalid path
$File = %WINDIR% + "\WRONG\MSPrint.inf"
$Section = "Uni"
ShowSection($File, $Section)
?

; Invalid parameter
$File = %WINDIR% + "\Inf\MSPrint.inf"
$Section = 0 ; Should be a string
ShowSection($File, $Section)
?

; No file handles available
$File = %WINDIR% + "\Inf\MSPrint.inf"
For $i = 1 To 10 ; Use all handles
$RC = Open($i, "$File")
Next
$Section = "Uni"
ShowSection($File, $Section)

?? "Press any key to continue... " Get $x

Return


Function ShowSection($File, $Section)

$SecArray = Split(ReadSection($File, $Section), Chr(10))
If @Error
? "Error: " + @Error + " " + @SError
Else
"Entries in section($Section): " ??
For Each $Member In $SecArray
$Member ?
Next
EndIf

EndFunction


Function ReadSection($File, $Section)

$ReadSection = ""
If VarType($File) <> 8
Exit 87 ; ERROR_INVALID_PARAMETER
EndIf
If VarType($Section) <> 8
Exit 87 ; ERROR_INVALID_PARAMETER
EndIf
$Handle = 0
Do
$Handle = $Handle + 1
$RC = Open($Handle, $File)
If $RC > 0 ; System error, Open() returns only negative error numbers
Exit $RC
EndIf
Until $Handle > 10 Or $RC = 0 ; Invalid handle or successfull open
If $RC
Exit 6 ; ERROR_INVALID_HANDLE
EndIf
$RetVal = ""
$Section = "[" + $Section + "]"
$Lin = ReadLine($Handle)
While @Error = 0 And RTrim(LTrim($Lin)) <> $Section
$Lin = ReadLine($Handle)
Loop
$Lin = LTrim(RTrim(ReadLine($Handle)))
While @Error = 0 And SubStr($Lin, 1, 1) <> "["
If $Lin
If $RetVal
$RetVal = $RetVal + Chr(10)
EndIf
$RetVal = $RetVal + $Lin
EndIf
$Lin = LTrim(RTrim(ReadLine($Handle)))
Loop
$ReadSection = $RetVal
$RC = Close($Handle)

EndFunction



Erik


PS:
You might wonder what i would need to use the function ReadSection() for!

It is for reading inf files. Inf files nearly follows the the rules for ini files, but this is allowed in an
inf file:

[UNI]
UNIDRV.DLL
UNIDRV.HLP
ICONLIB.DLL

Observe no =


Also if i need to read all entries in the section [386Enh] in System.ini, the section might look like this(Win9x):

[386Enh]
ebios=*ebios
mouse=*vmouse, msmouse.vxd
device=*dynapage
device=*vcd
device=*vpd

Observe, there is several device= statements, Read/WriteProfilestring will always read/write the first entry.

[This message has been edited by kholm (edited 18 May 2001).]

Top
#80106 - 2001-05-18 11:05 AM Re: Set @ERROR and @SERROR
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Ok, firstly this is the "suggestions" forum, not the "beta" forum. It's purpose is to raise ideas about how to improve Kix, or add features we'd like. These may get included in the next release, added to a wish list for future releases or be vetoed as not within the design philosophy of Kix. I'm sure if we are disturbing Ruud he'll let us know.

The point of user defined messages is
1) You can include far more relevant detail about the cause of the problem. For instance I have a number base conversion routine which raises an error if the character isn't valid for the number base. If you try to convert "678" from octal to decimal an error message saying "The character '8' is not valid for the base 8 number system" is much more useful than error 1804 "The specified data type is invalid" which was the closest I could find.
2) You don't have to search through all the messages trying to find one that fits and makes sense.
3) The error messages can be tailored to your local language(s)

Now, all of the above *can* be achieved with Kix as it is, using global error variables and so on. In the Kix community we could decide to adopt a standard - our UDFs should always set / reset the global variables $_UDF_ERROR and $_UDF_SERROR for example. This would give the same features, and if adopted as a standard would allow portable function libraries to be distributed. The point is, why do it? If a future release can support user defined error messages through the @SERROR macro let's do that.

------------------
Richard Howarth

Top
#80107 - 2001-07-15 06:52 AM Re: Set @ERROR and @SERROR
MCA Offline
KiX Supporter
*****

Registered: 2000-04-28
Posts: 5152
Loc: Netherlands, EU
Dear,

A great suggestion. By modifying our tool kixstrip option /debug
we were missing the possibility of resetting the @error value.
The way of setting it by the UDF SetError was briallant and very simple.

We were using it for the creation of an actual list of KiXtart error codes
(the description and not the mnemonics).
Our script is:

code:

$error_file="t:\kix-error.lst"
;
IF RedirectOutput($error_file,1)
ENDIF
? "KixTart "+@kix+" - Summary Error Codes"
?
FOR $i=0 TO 9999
SetError($i)
IF (len(@serror) <> 0) AND (Instr(@serror,"Error retrieving error information for") = 0) AND (Instr(@serror,", 13D)") = 0)
$pos=Instr(@serror,CHR(13)+CHR(10))
IF ($pos <> 0)
? Substr(" ",1,7-len("$i"))+"@error "+substr(@serror,1,$pos-1)+" "+substr(@serror,$pos+2,len(@serror)-$pos-1)
ELSE
? Substr(" ",1,7-len("$i"))+"@error "+@serror
ENDIF
ENDIF
NEXT
EXIT
FUNCTION SetError($error_number) EXIT $error_number ENDFUNCTION

The result of it is:

code:

KixTart 4.00 RC 1 - Summary Error Codes

0 (null) [0/0]
1 Incorrect function.
2 The system cannot find the file specified.
3 The system cannot find the path specified.
4 The system cannot open the file.
5 Access is denied.
6 The handle is invalid.
7 The storage control blocks were destroyed.
8 Not enough storage is available to process this command.
9 The storage control block address is invalid.
10 The environment is incorrect.
11 An attempt was made to load a program with an incorrect format.
12 The access code is invalid.
13 The data is invalid.
14 Not enough storage is available to complete this operation.
15 The system cannot find the drive specified.
16 The directory cannot be removed.
17 The system cannot move the file to a different disk drive.
18 There are no more files.
19 The media is write protected.
20 The system cannot find the device specified.
21 The device is not ready.
22 The device does not recognize the command.
23 Data error (cyclic redundancy check)
24 The program issued a command but the command length is incorrect.
25 The drive cannot locate a specific area or track on the disk.
.....
2000 The pixel format is invalid.
2001 The specified driver is invalid.
2002 The window style or class attribute is invalid for this operation.
2003 The requested metafile operation is not supported.
2004 The requested transformation operation is not supported.
2005 The requested clipping operation is not supported.
2202 The specified username is invalid.
2250 This network connection does not exist.
2401 This network connection has files open or requests pending.
2402 Active connections still exist.
2404 The device is in use by an active process and cannot be disconnected.
3000 The specified print monitor is unknown.
3001 The specified printer driver is currently in use.
3002 The spool file was not found.
3003 A StartDocPrinter call was not issued.
3004 An AddJob call was not issued.
3005 The specified print processor has already been installed.
3006 The specified print monitor has already been installed.
4000 WINS encountered an error while processing the command.
4001 The local WINS can not be deleted.
4002 The importation from the file failed.
4003 The backup Failed. Was a full backup done before ?
4004 The backup Failed. Check the directory that you are backing the database to.
4005 The name does not exist in the WINS database.
4006 Replication with a non-configured partner is not allowed.



A complete list you can find on topic
http://kixtart.org/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=1&t=002663
It is also very easily to translate above error descriptions in other languages
and to use them in your own scripts.
Greetings.
_________________________
email scripting@wanadoo.nl homepage scripting@wanadoo.nl | Links | Summary of Site Site KiXforms FAQ kixtart.org library collection mirror MCA | FAQ & UDF help file UDF kixtart.org library collection mirror MCA | mirror USA | mirror europe UDF scriptlogic library collection UDFs | mirror MCA

Top
Page 1 of 1 1


Moderator:  Lonkero, ShaneEP, Jochen, Radimus, Glenn Barnas, Allen, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 248 anonymous users online.
Newest Members
gespanntleuchten, DaveatAdvanced, Paulo_Alves, UsTaaa, xxJJxx
17864 Registered Users

Generated in 0.07 seconds in which 0.025 seconds were spent on a total of 12 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org