How to? A question about error-handling...

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
#1
I apologize in advance if the way to do this (assuming it even can be done) is well documented; but I've looked for it without any success finding it if is there; could be my bad memory and/or bad eyesight.

See, the problem is this: In many of the batch files that I write, some errors are even "expected" once in a while, and I use an "On Error" statement to "catch" and then "handle" these errors. However, it is also true that many times (particularly due to "coding errors" on my part) the errors are not the errors that I would "expect". Unfortunately, once an error has happened and been "caught", I'd like to exactly "regenerate" the error if is not an error I expected and then "recreate" it; or even better, have the batch file terminate producing the appropriate error message; and I have no idea how to do that. (I'll add here that not knowing exactly what "caused" the error in the first place so I can take the "appropriate action" has also been a problem; I've "worked around that by setting one or more "flags" before statements that I expect could have an error, and resetting that flag after that statement has been completed; I am, of course, assuming in doing this that the only error(s) that the "guarded" statement could "produce" is one of the error(s) that I "expect" could happen, and I am therefore making a fairly big assumption that it is, in fact, one of the "expected" error and not something else; a "coding" error most likely.)

So is there any (known) technique to do this?

- Dan
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,385
39
Albuquerque, NM
prospero.unm.edu
#2
I'm not at all clear on what you're trying to do. Can you give a brief example?

But it seems to me that an "expected error" is also a preventable error. For instance, if you know that a number used as a divisor might be zero, then you can check for the zero before performing the division.
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#4
I think he wants to essentially reraise an exception. I don't know any way to do that in TCC.
No, there's no way to do that. I could conceivably implement something like that, but (1) it would be exceptionally tricky in Windows (since most of the errors are occurring in Windows, not in TCC), and (2) nobody's asked for it in 20 years, so I don't think it's got a ready audience.
 

samintz

Scott Mintz
May 20, 2008
1,204
11
Solon, OH, USA
#5
Assuming you are using the ON ERROR statement, what command do you execute? If you GOSUB an error handler, you should be able to display the error if it is not handled and then QUIT. The errors are generally available via the %_? and %_SYSERROR variables.

You can use @ERRTEXT to display a system error string: echo %@ERRTEXT[%_SYSERROR]. I couldn't find an equivilent function for a TCC error returned in %_?.

Is there a way to display the text that ON ERRORMSG would display from within a ON ERROR handler?
 
#6
Sorry I haven't gotten back to this for a couple of days; it's simply because I've been truly overwhelmed (actually, nothing at all out of the ordinary for me given the glacial pace at which I manage to actually accomplish anything), and the simple fact is that it is really questionable whether doing this is the top "priority" in my list of probably 40 to 50 things (sadly, neither a joke nor an exaggeration!!!) I have to accomplish the sooner the better. But, for whatever reason, this is at the top of my priorities as of this moment.

And Charles, the first and most important thing I want to accomplish (there are sometimes a few things that are logically similar to "end of file" but you get a "hard" error rather than a "nice" "end of file-"like indication) is to have a .btm file to both terminate when an error occurs (as an example, sometimes continuing can be very "damaging" because the batch file continues to do things (like delete files that it really shouldn't delete but is deleting as a "side effect" of the error) and the fact that I put an error-handler into the batch file I can longer see what the error(s) actually was(/were). For me, a very bad "catch-22".

So it's like this:

Here's a simple .BTM file named "IllustrateErrorHandling":

Code:
  @Echo Off
  Set RC=0
  If "%1" == "RC" On Error Set RC=8
  If "%1" == "MSG" On Error Goto HaveError
  ANonExistentCommand
  AnotherNonExistentCommand
  @Echo RC: %RC
  Quit
:HaveError
  @Echo **** %@ERRTEXT[%_SYSERROR]
  Quit
And here's a really about as simple as it possibly could be .BTM file named "EchoArgument.btm":
Code:
@Echo %1
Here are the results(s) of running ""IllustrateErrorHandling" all three possible ways, as well as the effective, but mostly silent, almost total "destruction" (if you want to know exactly what I mean by that word, read further) of the TCC session in which the command is executed:
Wed Dec 21, 2011 12:44:35p

ISO8601 plugin v1.1.1 loaded.
SafeChars plugin v1.5.7 loaded.

TCC 12.11.76 Windows 7 [Version 6.1.7601]
Copyright 2011 Rex Conn & JP Software Inc. All Rights Reserved
Registered to Daniel Mathews

[Z:\]EchoArgument Argument
Argument

[Z:\]IllustrateErrorHandling
TCC: Z:\IllustrateErrorHandling.btm [5] Unknown command "ANonExistentCommand"
TCC: Z:\IllustrateErrorHandling.btm [6] Unknown command "AnotherNonExistentCommand
"
RC: 0
[Z:\]EchoArgument Argument
Argument

[Z:\]IllustrateErrorHandling RC
RC: 8

[Z:\]EchoArgument Argument
Argument
So, to start, everything is working OK up to this point.
[Z:\]IllustrateErrorHandling MSG
^C
Notice that the "" .BTM file just "hung" in the last "step" in the above, and I had to hit Ctrl-C to "get out of it. But after that, the "execution engine" for batch files was completely "broken", as none of the below attempted batch file executions did anything at all:
[Z:\]IllustrateErrorHandling

[Z:\]IllustrateErrorHandling RC

[Z:\]IllustrateErrorHandling MSG

[Z:\]IllustrateErrorHandling RC

[Z:\]EchoArgument Argument
Again note that absolutely none of the above "commands" (i.e., executing ".btm" files) did absolutely anything at all. However, I will note that it is "limited" to only batch files:
[Z:\]Echo Internal commands still work...
Internal commands still work...

[Z:\]notepad "A Sample Text File.txt"
This only "sort of" worked in that, while Notepad did "start up", the TCC session totally "hung" until the Notepad program was "closed" (ala the "Start" command with the "/WAIT" option).

However, since I have a very high reliance on (many!) batch files that are essentially "crutches" of one kind or another for my disabilities, this effectively makes that TCC session totally useless for me.

And to give you some idea of how many "many" is in terms of the number of batch files that I have "under development" is that number is 40 (yes, I have a hard time believing that number myself!). But there's actually 175 .btm files on my RAM disk as of this second; "40" is gotten by subtracting the number of .btm files with "Test" as the first 4 letters of their names (30 of them) because the are batch files that were purely created to test other batch files, the number of .btm files with the "Exper" as the first 4 characters of the name (38 of them), the character string ".V2011-" in its name (14 of them) because when I start a new "version" of a batch file based on a "previous" version that is mostly working), and those with whose names are "*-#" or "*+#" (40 of them, where "#" represents an arbitrary "number") because these are either "back" versions of a .btm file that I really don't intend to keep (except for "reference purposes" for a limited period of time, the negative numbers) or purely experimental "new" versions where I have not yet decided to "follow the path" that the "experiment" suggests (the positive numbers), or whose names "end" with a Roman Numeral (12 of them; I don't name files that way all that often). (And all of these numbers are actually accurate thanks to a large degree to the "wonders" of TCC! I've attached a file listing all of these files to this posting if you are curious and want to look at it because you don't quite believe me.)

And, one final "odd" thing that I haven't been able to consistently repeat up to now: Sometimes typing the "Exit" command "works" and usually ends the TCC session, but sometimes it does not and I have to close the TCC session by "hitting" the "close" button (little "x" on the top right of the tab) to close the TCC session. Admittedly, this is only a minor annoyance for me, but, while I used to be an exceptionally fast typist before my disabilities got the "better of me", I'm still a fairly fast typist now, but having to use the mouse (actually the touch pad on this laptop) is a pain in the rear for me, to put it "nicely". I can probably go for literally hours with out ever touching the touch pad or a touch pad button.

And if this a problem that can't be fixed (I have to admit I really don't understand that as a person who at least used to be a very good programmer, Rex - why are the details of the errors/error messages no longer available when you go into a error handler? A purely rhetorical question...), this truly is a very big problem for me because of the multitude of errors I make on an almost-continual basis; I swear, I can write two lines of code and have 10 errors!!! But I truly have no other viable choice but to use TCC because these problems are significantly "enhanced" in C++ programs, primarily because of the typically vastly larger amount of code has to be written (more code, more chances for error and therefore more errors) to get much of anything done and the fact that executing arbitrary TCC commands in batch files (ala "@ExecStr" and "@ExecArray") is another large pain in the the rear, to put it politely).

And something I may or may not have said before (I wouldn't necessarily remember): Because of the severity two of my two most severe disabilities (extremely bad memory and a total inability to write - as in a pen or pencil and paper), to say I would probably have to be institutionalized as of this minute were it not for this computer and Take Command and TCC would be a considerable understatement. So thank you again, Rex!

- Dan
 

Attachments

#7
The problem is that there is no %_SYSERROR. It should be %_SYSERR. So, you had an error in your error handler, thus producing an infinite loop. If you look at the bottom of the Help page for ON, you'll see a caution about this happening. I suggest you put "on error" on the line after ":HaveError" to restore the default handler.

I don't know why TCC is messed up after you kill the infinite loop, but I see it too.
 
#8
Thank you, Dave, but only a small and basically totally irrelevant "improvement". So here's things stand now - the error code has been "corrected" and "improved" as you suggested (I'm only including the small part of the .btm file that I actually changed):
Code:
:HaveError
  @Echo On
  Set ErrorCodeR=%_SYSERR
  On Error Goto ErrorInErrorHandler
  @Echo %%_SYSERR: %ErrorCodeR
  Echo **** %%@ERRTEXT[%%ErrorCodeR]
  Echo **** %%@ERRTEXT[%ErrorCodeR]
  Echo **** %@ERRTEXT[%ErrorCodeR]
  Quit
:ErrorInErrorHandler
  @Echo Error within error!!!
  Quit
And the results are identical (as they should be) for both no parameter at all to the batch file and for a parameter of "RC". However, for the "MSG" parameter, here's the results:
Set ErrorCodeR=0
On Error Goto ErrorInErrorHandler
%_SYSERR: 0
Echo **** %@ERRTEXT[%ErrorCodeR]
**** %@ERRTEXT[%ErrorCodeR]
Echo **** %@ERRTEXT[0]
**** %@ERRTEXT[0]
Echo **** The system could not find the environment option that was entered.

**** The system could not find the environment option that was entered.
Quit
Two points here:

1. I don't have a clue what the error message "The system could not find the environment option that was entered." is even supposed to mean (it's certainly not "Unknown command ...").

2. Executing "Echo %@ERRTEXT[0]" directly from the command line produces "The operation completed successfully.", what one would hope for and expect. So why the clear-cut "**** %@ERRTEXT[0]" in the above batch file produces "**** The system could not find the environment option that was entered." is certainly beyond me.

And one last point which is somewhat of a "suggestion" Rex, and doing this would pretty much entirely circumvent the "problem(s)" I am having. First off, I'm not really expressing any "opinion" here, but the TCC batch-file language is unique in terms of all of the other languages I've used in the past: When a error happens, the "default behavior" of the batch-file language interpreter is to automatically continue execution (unless that is not even possible, of course). And the "cure" for this is relatively simple, at least in principle: Provide an "option" that says when an error happens the error message will be displayed (as is done now) but then batch file will be terminated (a "cancel" might even appropriate). I could be wrong of course, but I don't even think this would be a major change in terms of coding (other than you would have supply "support" for that new option in all of the place(s) that "options" can be specified/changed). And if you can display the error message(s) you get from Windows now, I can't see how terminating the batch file after displaying the error message would change that in any way.

- Dan
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#9
Code:
Set ErrorCodeR=0
On Error Goto ErrorInErrorHandler
%_SYSERR: 0
Echo **** %@ERRTEXT[%ErrorCodeR]
**** %@ERRTEXT[%ErrorCodeR]
Echo **** %@ERRTEXT[0]
**** %@ERRTEXT[0]
Echo **** The system could not find the environment option that was entered.
 
**** The system could not find the environment option that was entered.
Quit
Not reproducible here. I get:

Code:
Set ErrorCodeR=2
On Error Goto ErrorInErrorHandler
%_SYSERR: 2
Echo **** [EMAIL]%@ERRTEXT[%ErrorCodeR]
**** [EMAIL]%@ERRTEXT[%ErrorCodeR]
Echo **** [EMAIL]%@ERRTEXT[2]
**** [EMAIL]%@ERRTEXT[2]
Echo **** The system cannot find the file specified.
**** The system cannot find the file specified.
Quit
Which is what I would expect to see.

You've probably got something interfering with the expected command flow -- either a plugin, or an UNKNOWN_CMD alias. Try running it with no plugins or aliases loaded.

(Note that %_SYSERR will only be set if an error message would be displayed.)
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#11
And one last point which is somewhat of a "suggestion" Rex, and doing this would pretty much entirely circumvent the "problem(s)" I am having. First off, I'm not really expressing any "opinion" here, but the TCC batch-file language is unique in terms of all of the other languages I've used in the past: When a error happens, the "default behavior" of the batch-file language interpreter is to automatically continue execution (unless that is not even possible, of course).
For compatibility with CMD. And many errors are benign (like MD existingdirectory, or DIR nonexistentfile).
 
#12
I'm getting what Dan gets:
Code:
C:\Junk>type Foo.btm
@echo Off
setlocal
unalias *
on error goto HaveError
ANonExistentCommand
quit
:HaveError
set ErrorCodeR=%_SYSERR
echo %%_SYSERR: %ErrorCodeR
echo %@ERRTEXT[%ErrorCodeR]
 
C:\Junk>Foo.btm
%_SYSERR: 0
The system could not find the environment option that was entered.
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#13
And, one final "odd" thing that I haven't been able to consistently repeat up to now: Sometimes typing the "Exit" command "works" and usually ends the TCC session, but sometimes it does not and I have to close the TCC session by "hitting" the "close" button (little "x" on the top right of the tab) to close the TCC session.
Not reproducible here -- and if there was a general problem with EXIT, I'd have thousands of bug reports, not one! :-)

Do you have a TCEXIT file? That's almost always the cause of exit problems.

And if this a problem that can't be fixed (I have to admit I really don't understand that as a person who at least used to be a very good programmer, Rex - why are the details of the errors/error messages no longer available when you go into a error handler?
They are -- %? and %_? will display the external/internal error numbers. Error messages are suppressed because 99.9999% of the time you wouldn't want to see them in an error handler. (If you do want to see them, use ON ERRORMESSAGE instead.)
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#14
I'm getting what Dan gets:
Code:
C:\Junk>
C:\Junk>Foo.btm
%_SYSERR: 0
The system could not find the environment option that was entered.
I can't reproduce that here, but I can explain the error message. If you pass a <= 0 argument to %@ERRTEXT, it assumes you've made a mistake (why would you want to print an error message if you didn't have an error?), so it calls the Windows GetLastError() API. (As to why Windows is returning that particular error number -- you'll have to ask Microsoft.)

The other point that you and Dan are missing, is that an "unknown command" is NOT a Windows error, so expecting Windows to return a reasonable error code for something it doesn't know anything about is, well, unreasonable. "Unknown command" is an internal TCC error, so it returns the normal error exit (2) to ON ERROR, where you could query it with %_?.
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#15
I'm getting what Dan gets:
Code:
C:\Junk>type Foo.btm
@echo Off
setlocal
unalias *
on error goto HaveError
ANonExistentCommand
quit
:HaveError
set ErrorCodeR=%_SYSERR
echo %%_SYSERR: %ErrorCodeR
echo %@ERRTEXT[%ErrorCodeR]
 
C:\Junk>Foo.btm
%_SYSERR: 0
The system could not find the environment option that was entered.
Try it with the correct syntax:

@echo Off
setlocal
unalias *
on error ( set ErrorCodeR=%_? & goto HaveError )
ANonExistentCommand
quit
:HaveError
echo on
echo Error: %ErrorCodeR
echo %@errtext[%ErrorCodeR]

You should be setting the error code in the ON ERROR statement -- a GOTO will reset internal errors and potentially external errors as well (depending on the syntax and result).
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#17
The Help could mention that GOTO will reset the errors and give an example of how to save the error number.
That would get a bit cumbersome -- every CMD-compatible internal command (except ECHO, IF, and SET) will set the errorlevel. (This is covered generally in the help, but not in each individual command.)

This is all for CMD compatibility, and I usually don't go into great detail on things that behave identically to CMD.
 
#18
That would get a bit cumbersome -- every CMD-compatible internal command (except ECHO, IF, and SET) will set the errorlevel. (This is covered generally in the help, but not in each individual command.)
I meant on the Help page for ON give the example, "on error ( set ErrorCodeR=%_? & goto HaveError )". This isn't obvious. It doesn't need to be mentioned anywhere else.
 
#19
Thank you very much, guys!!! I tend to thing (although I could certainly be wrong! :) ) that this will terminate this whole discussion. So, going through things one-by-one:

"*on errormsg cancel": Clearly I was not aware of that, and as a "general" "safety measure" that can be "turned off" in those cases where it is clearly not appropriate and turned back on again afterwords, it is an almost perfect "safety catch" for me. (Slightly inconvenient sometimes I suppose, but a rather minor "hardship"). And Rex, this is a compliment. Your product has got so many capabilities/features that I wasn't completely able to "keep up" with them even before my memory loss essentially became crippling. (As I think I've mentioned before, I finally, after literally years of trying, to convince a good friend to buy and try the product. However, he told me within a day or two after installing it that "that there was so much there that it was overwhelming!") As always, thank you very much!

And this is a (not very important) question, but I really don't understand (and "really not understanding" has always rather deeply "bothered" me): You (Rex) say: "Try it with the correct syntax:", and show " %@errtext[%ErrorCodeR]" to illustrate what the "correct syntax" is. However, my code had "%@ERRTEXT[%ErrorCodeR]" . The only difference that I see here (am I truly now that crazy?) is letter case. What am I missing?

And on a humorous (at least to me) aside, Rex, your total adherence to "cmd.exe" compatibility, while I completely understand it and don't disagree with it all all, is a real millstone around your neck, as the saying goes. For somebody like me, who has been using some version of your product since Windows 3.1, I could not care less about being "compatible" with cmd.exe because I don't use and have absolutely no reason to use (other than "comparing" with TCC) cmd.exe; being "compatible" with something that is basically stupid is, unfortunately, not basically stupid.)

And on another minor point, "dir" commands that return no matching files or "MD" on an already existing directory are absolutely perfect examples of what I referring to when I said "there are sometimes a few things that are logically similar to 'end of file' but you get a 'hard' error rather than a 'nice' 'end of file-' like indication", and now that I realize exactly what I referring to when I made that statement (bad memory, as always), these kinds of things occur on an almost continuous basis. Unfortunately, I couldn't think of any examples of them at time I wrote that because, even independently of my bad memory, I mostly only really think about them when they occur. And Charles, I think that that is a almost perfect example of why "it seems to me that an 'expected error' is also a preventable error" is not really generically true; while I suppose that it might be possible to "anticipate" all of these kinds of errors before they occur, the "coding costs" of doing so doing so could become quite prohibitive, and the "performance" of said batch file could be severely impacted. (Letting the "error" happen and then "catching" it is a far better generic solution in many if not most situations.)

And, as what I suppose is a purely "philosophical" musing, Rex, you are, of course, correct when you say "`unknown command` is NOT a Windows error, so expecting Windows to return a reasonable error code for something it doesn't know anything about is, well, unreasonable". However, from my perspective as a coder, an error is an error and I really couldn't generically care less whether it is a Windows error or a TCC error. However, with the "solutions" that been suggested in this thread, I don't think it really matters any more.

And I have no clue as to why the "Exit" command didn't work, I just know without any doubt whatsoever that it often didn't work because in those cases I was forced to use the mouse (touch-pad) and hit the "close" button - and I am very touch-pad/buttons adverse. (And I do not and have never had a "TCExit" file.) But I haven't spent a whole lot of time trying to "repeat" these things because it really doesn't matter that much anymore...

Again, thank you all!!!

- Dan

P. S. And I will add that, due to my basic incompetence at this point in my life due to my memory loss, in particular, typing something like this and getting it even close to being correct is a slow, "agonizing" process. The only reason that that is not (completely, at least) obvious is because I have a myriad of well-developed "strategies" for dealing with the "situation".
 

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#22
And this is a (not very important) question, but I really don't understand (and "really not understanding" has always rather deeply "bothered" me): You (Rex) say: "Try it with the correct syntax:", and show " %@errtext[%ErrorCodeR]" to illustrate what the "correct syntax" is. However, my code had "%@ERRTEXT[%ErrorCodeR]" . The only difference that I see here (am I truly now that crazy?) is letter case. What am I missing?
I was referring to the correct syntax for the ON ERROR statement:

on error ( set ErrorCodeR=%_? & goto HaveError )

You had the error assignment after the goto label (by which time the error code would have been changed), and you were referencing %_SYSERR when you should have been referencing %_? (because "Unknown Command" is a TCC error, not a Windows error).

And on a humorous (at least to me) aside, Rex, your total adherence to "cmd.exe" compatibility, while I completely understand it and don't disagree with it all all, is a real millstone around your neck, as the saying goes. For somebody like me, who has been using some version of your product since Windows 3.1, I could not care less about being "compatible" with cmd.exe because I don't use and have absolutely no reason to use (other than "comparing" with TCC) cmd.exe; being "compatible" with something that is basically stupid is, unfortunately, not basically stupid.)
That comes up periodically, to which I have two replies:

1) The same people who say "I don't care at all about CMD compatibility" are the same people who then send me aggrieved bug reports about TCC not emulating some bizarre undocumented CMD behavior. Nobody cares about CMD compatibility until they want to run a CMD batch file! (And they always do ...)

2) Being CMD compatible makes it easy for new users to start using Take Command / TCC (and have it immediately work better than CMD), and they can learn the extended features at their own pace. Inventing a completely new syntax would cut the potential audience drastically -- if you had to relearn everything from scratch, you might as well switch to Linux. :D
 
#23
Thank you for your quick response, Rex! And, as I indicated in the posting that prompted your response, I totally understood and did not disagree (even slightly!!!!) with your decision ("being 'compatible' with something that is basically stupid is, unfortunately, not basically stupid.") The fact that cmd.exe is so stupid is Microsoft's fault, not yours. (And I am certainly not one of the people who would fall into category number 1, but that's just me. I am absolutely not one of the (probably many!) "they" you are referring to.)

And I totally understand and agree with #2, above, being the reason why you made that decision - even I think, and have always thought, that it was (unfortunately for me! :)) the best decision. (Particularly since, as I've said, TCC has so many new features/capabilities as to be (sadly! but inherently, I think) overwhelming to new users.)

- Dan
 
#24
The same people who say "I don't care at all about CMD compatibility" are the same people who then send me aggrieved bug reports about TCC not emulating some bizarre undocumented CMD behavior. Nobody cares about CMD compatibility until they want to run a CMD batch file! (And they always do ...)
May I cry foul on that?? I've been one of those who has expressed a complete lack of interest in MS command line compatibility over the years (dating back to the Compuserve days, I suspect), preferring internal consistency instead, and I have never wanted to run a CMD batch file in any of your products. I am quite happy to fire up CMD to run such batch files, which has always seemed to me to be the most logical approach.