Shadoninja
Shadoninja

Reputation: 1496

Is there an easy way to capture the error code (%errorlevel%) from a nested batch script?

I have a nested batch script and I want my error codes from it to percolate up to the main batch script that called it. I have tried

exit /b %errorlevel%

but the variable doesn't make it back. ECHO'ing %errorlevel% in the called batch script gives me 103, but ECHO'ing %errorlevel% in the main batch script (the very next line in terms of execution) gives me 0. This question has been asked on SO before, but none of the posts have worked for me.

EDIT: Due to poor writing, I have revised my question and also will add the code for you to see.

Here is the main batch file. The if statement here is never hit unless I change the condition to something other than 0:

call BuildInstaller.cmd %SourceDir% %TargetDir% %ProductVersion% %%I
if %errorlevel% neq 0 (
    ECHO %date% %time%: Build of %%I failed, halting >> %LOGFILE%
    exit /b %errorlevel%
)

Here is where BuildInstaller.cmd exits. I have cleaned up the prints to avoid confusion:

if %errorlevel% neq 0 (
    exit /b %errorlevel%
)

As a side note, I also tried doing

set returnvalue=12

in the called batch script, but ECHO'ing %returnvalue% in the main batch script was always one execution of the program behind. If anyone knows the answer to this sub-question, that would be cool to know.

Upvotes: 1

Views: 1348

Answers (2)

Aacini
Aacini

Reputation: 67216

You have the classical Delayed Expansion error. See this example:

call BuildInstaller.cmd %SourceDir% %TargetDir% %ProductVersion% %%I
if %errorlevel% neq 0 (
    ECHO %date% %time%: Build of %%I failed, halting >> %LOGFILE%
    exit /b %errorlevel%
)

This is BuildInstaller.cmd:

@echo off
setlocal EnableDelayedExpansion

if 1 == 1 (
   rem Inside a code block, %errorlevel% have the same value it had before the block
   rem (its %value% is NOT updated inside the block) so you need to use !errorlevel!
   rem in order to get the *updated* value

   verify set errorlevel = 1
   if !errorlevel! neq 0 (
      exit /b !errorlevel!
   )
)

exit /B

For further details, look for "Delayed Expansion".

Upvotes: 2

miltonb
miltonb

Reputation: 7355

The errorlevel is set after each command has been executed. So the error level of 0 is the result of the statement after the one that created error level 103.

To illustrate with multiple batch files:

sub.bat:

 rem This is invalid argument for zip which sets errorlevel
 zip -QQ

test.bat:

 @echo off
 call sub.bat
 echo %errorlevel%

Example output which the first line comes from zip:

zip error: Invalid command arguments (no such option: Q)
16

Upvotes: 1

Related Questions