There's a lot of advice out there for dealing with return codes in batch files (using the ERROLEVEL mechanism), e.g.
Some of the advice is to do if errorlevel 1 goto somethingbad
, while others recommend using the
%ERRORLEVEL%
variable and using ==
, EQU
, LSS
, etc. There seem to be issues within IF
statements and such, so then delayedexpansion is encouraged, but it seems to come with quirks of its own.
What is a foolproof (i.e. robust, so it will work on nearly any system with nearly any return code) way to know if a bad (nonzero) code has been returned?
For basic usage, the following seems to work ok to catch any nonzero return code:
if not errorlevel 0 (
echo error level was nonzero
)
To test for a specific ERRORLEVEL, use an IF command with the %ERRORLEVEL% variable. n.b. Some errors may return a negative number. If the batch file is being executed as a scheduled task, then exiting with an error code will be logged as a failed task. You can monitor the event log to discover those failures.
Batch file error level: %ERRORLEVEL% is an environment variable that contains the last error level or return code in the batch file – that is, the last error code of the last command executed. Error levels may be checked by using the %ERRORLEVEL% variable as follows: IF %ERRORLEVEL% NEQ 0 ( DO_Something )
Sorry, your attempt is not even close. if not errorlevel 0
is only true if errorlevel is negative.
If you know that errorlevel will never be negative, then
if errorlevel 1 (echo error level is greater than 0)
If you must allow for negative errorlevel, and are not within a parenthesized block of code, then
set "errorlevel=1"
set "errorlevel="
if %errorlevel% neq 0 (echo error level is non-zero)
Note - I edited my answer to explicitly clear any user defined errorlevel value after reading Joey's comment to the linked answer in the question. A user defined errorlevel can mask the dynamic value that we are trying to access. But this only works if your script has a .bat
extension. Scripts with .cmd
extension will set your ERRORLEVEL to 0 if you set or clear a variable! To make matters worse, XP will set ERRORLEVEL to 1 if you attempt to undefine a variable that does not exist. That is why I first explicitly define an ERRORLEVEL variable before I attempt to clear it!
If you are within a parenthesized block of code then you must use delayed expansion to get the current value
setlocal enableDelayedExpansion
(
SomeCommandThatMightGenerateAnError
set "errorlevel=1"
set "errorlevel="
if !errorlevel! neq 0 (echo error level is non-zero)
)
But sometimes you don't want delayed expansion enabled. All is not lost if you want to check the error level immediately after executing a command.
(
SomeCommandThatMightGenerateAnError && (echo Success, no error) || (echo There was an error)
)
If you absolutely must check the dynamic ERRORLEVEL value without using delayed expansion within a parenthesized block, then the following works. But it has the error handling code in two places.
(
SomeCommandThatMightGenerateAnError
if errorlevel 1 (echo errorlevel is non-zero) else if not errorlevel 0 (echo errorlevel is non-zero)
)
Here, at long last, is the "ultimate" test for non-zero errrolevel that should work under any circumstances :-)
(
SomeCommandThatMightGenerateAnError
set foundErr=1
if errorlevel 0 if not errorlevel 1 set "foundErr="
if defined foundErr echo errorlevel is non-zero
)
It can even be converted into a macro for ease of use:
set "ifErr=set foundErr=1&(if errorlevel 0 if not errorlevel 1 set foundErr=)&if defined foundErr"
(
SomeCommandThatMightGenerateAnError
%ifErr% echo errorlevel is non-zero
)
The macro supports parentheses and ELSE just fine:
%ifErr% (
echo errorlevel is non-zero
) else (
echo errorlevel is zero
)
One last issue:
Redirection of input and/or output can fail for any number of reasons. But redirection errors do not set the errorlevel unless the ||
operator is used. See File redirection in Windows and %errorlevel% for more information. So one can argue that there does not exist a fool-proof way to check for errors via errorlevel. The most reliable method (but still not infallible) is the ||
operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With