What I'm doing
I'm trying to simulate exception handling in batch. I know theres a forum post on DosTips that goes extensively into this topic and even provides a script that does some of what you would expect. Since this is a work project I can't use their solution so I tried my own hand at this.
How I'm trying to do it
I've tried to implement what I'll call the "poor man's try catch" which is really just a FOR
loop that runs batch commands line by line and if the errorlevel
is above 0, the line is caught by the loop in an IF
from the DO
clause. For example, I tried writing this in batch:
@echo OFF
SET /A "LineCount=1"
FOR /F "tokens=* delims=" %%A IN ('SET "VarATest^=something" ^^ SET "VarBTest^=somethingelse" ^^ SE "VarCTest^=syntaxerror"') DO (SET /A "LineCount=1+!LineCount!" & IF !ERRORLEVEL! EQU 1 (echo errorlevel was: "!ERRORLEVEL!" and line was "!LineCount!") ELSE (echo line worked))
pause
Basically what the above is supposed to do is, initialize a LineCount
variable, run the three batch commands in the IN
clause (seperated by the ^
line enders) and for each line, increment the LineCount
and check to see if the line caused an errorlevel
of anything higher than 1 (!ERRORLEVEL! EQU 1
has that odd behavior). The third line has an obvious syntax error, the SET
is spelled SE
which should cause an errorlevel
higher than 0. The point is demonstration, this could be refined but right now its simply for proof of concept.
the problem
Unfortunately when I ran this code it didn't run anything as expected, instead all I get is the pause output but no errors. I don't beleive its running the IN
clause line by line as I expected so my question is this:
A. Is it possible to run batch commands line by line in the IN
clause of a FOR
loop to simulate a try catch? Obviously this means using delayed expansion and escape characters more frequently, but it'd be cool to have this rudimentary functionality.
B. If it is possible then what is the proper way to make the input of the IN
clause be raw text but also multiline at the same time. For example, the IN
clause right now is:
(SET "VarATest^=something" ^^ SET "VarBTest^=somethingelse" ^^ SE "VarCTest^=syntaxerror")
which I want to be functionally similar to the regular batch code of:
SET "VarATest=something"
SET "VarBTest=somethingelse"
SE "VarCTest=syntaxerror"
Where the third line obviously causes an error. I don't want to use another file if possible so no tempfiles that hold the try block code. Would I use the ^
line ender? I tried ^^
thinking I needed to escape the first line ender. I also tried newlines where the ^^
were but that didn't work either. I tried modifying delims to try and split the commands that way, maybe run them each that way but still I get no output.
EDIT:
edited out noise, tried answer provided which was extremely helpful but unfortunately did not yeild the solution however after tinkering I came up with this:
@echo OFF && setlocal enableextensions enabledelayedexpansion
SET lf=^&echo/^^
SET /A "LineCount=0"
FOR /F "tokens=*" %%A IN ('call!lf!SET "VarATest^=something"!lf!SET "VarBTest^=somethingelse"!lf!SET "VarCTest^=syntaxerror"!lf!') DO (SET /A "LineCount=1+!LineCount!" && echo ER: "!ERRORLEVEL!" or "%ERRORLEVEL%" A: "%%A" && IF !ERRORLEVEL! NEQ 0 (echo errorlevel was: "!ERRORLEVEL!" and line was "!LineCount!") ELSE (echo line worked = !LineCount!))
pause >nul
echo/!LineCount! && pause >nul
now this is mostly the answer provided with a few caveats. Adding in the "tokens=*"
part actually gets the full SET
line. The answer provided the linefeed mechanism. With experimentation I observed that a call!lf!
was needed BEFORE the first command in the "string". I have absolutely no idea why but it doesn't work any other way because the FOR
loop seems to want to skip the first argument. I got a printout of each command line in the string through %%A. fantastic! The only problem though, is that errors are not caught when they should be. ERRORLEVEL
does not seem to change when I change the last command string from
SET "VarCTest^=syntaxerror"
to:
ST "VarCTest^=syntaxerror"
or any similar variations that would cause an error to be thrown.
The issue is the SET
commands are never actually ran. Running an echo of them after the FOR
loop reveals this. I'm going to try and get them running