Intro
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.
Question
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?
My attempt
For basic usage, the following seems to work ok to catch any nonzero return code:
if not errorlevel 0 (
echo error level was nonzero
)
Sorry, your attempt is not even close.
if not errorlevel 0is only true if errorlevel is negative.If you know that errorlevel will never be negative, then
If you must allow for negative errorlevel, and are not within a parenthesized block of code, then
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
.batextension. Scripts with.cmdextension 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
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.
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.
Here, at long last, is the “ultimate” test for non-zero errrolevel that should work under any circumstances 🙂
It can even be converted into a macro for ease of use:
The macro supports parentheses and ELSE just fine:
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.