Exit codes need some tweak

A backup job just had a connection problem:

INFO REPOSITORY_SET Repository set to [redacted]
INFO STORAGE_SET Storage set to [redacted]
ERROR STORAGE_CREATE Failed to load the file storage at [redacted] ...

It was only by luck that I discovered the problem, as I noticed the small log file.

The monitoring by the exit codes didn’t notify me, as the error doesn’t correspond to any of these types, then the exit code was zero:

Considering also what was exposed in this issue:

I really don’t think it is correct a “zero” exit code for an unrealized backup.

1 Like

I just found the cause of the problem, and it is not related to Duplicacy. It is correctly returning the “100” error in the above connection problem.

The cause is related to “when” scripts evaluate the errorlevel variable. Basically related to the use of the ! character in the variables.

More details can be found here (there are many other sources about it).

I already used EnableDelayedExpansion in my scripts, without major problems.

The solution to the above errorlevel check problem was only change the position (order) of the line performing the test.

But I still think it’s relevant the problem reported in Github issue by @alessandro

Hi @towerbr!

Nice that Duplicacy is giving the exit code you wanted!

Not sure I understood the problem though, and a bit curious since I too rely on exit codes!

With delayed expansion enabled, !errorlevel! is normallty expanded on the “same line” if you do it like this, with two consecutive commands on one line:

SETLOCAL EnableDelayedExpansion
Duplicacy.exe backup & echo !errorlevel!

REM or execute if failed:
Duplicacy.exe backup || (echo Backup failed with exit code: !errorlevel! & goto :EOF)

REM and still other ways!

Would love to see a sample, but the important thing is you got it working of course :smile: !

The problem, as I realized, was that there was a set [variable] command right after the backup, and the exit code seemed to be returning “0” for executing this set command, not backup.

From my previous understanding the return would be only for executables, not commands. Lesson of the day learned.

It was enough to capture the errorlevel in a variable right after the backup was executed, and to use this variable from then on.

Glad you solved it!
I believe your original understanding is still correct!
Echo and Set does not set or reset the Errorlevel system variable, at least not in Windows 7 and later. (Batch files - Errorlevels)

If duplicacy output is piped to another command, like the Find command, Find will pass on the matching data and set the exit code so you can make choices based on the result of the complete pipeline. (Piping data through commands will return the exit code from the last command)

An example which loses the first exit code
"C:\Program Files\Duplicacy\duplicacy.exe" -log backup -stats | find "ERROR"
REM Errorlevel now contains the result of the Find command (not Duplicacy result)
REM And it will be 0 only if the logfile contains the word ERROR
echo The last command result: %errorlevel%

Like you say, one could first backup (saving the output to a file is fine), save the exit code in a new variable, then you can investigate file with other commands.

Save backup exit code first
"C:\Program Files\Duplicacy\duplicacy.exe" -log backup -stats > %Log%
set Error=%errorlevel%
type %Log% | find "ERROR" > %Tempfile%
REM %Error% should still have duplicacys exit code
REM %errorlevel% should contain the result of the find command

Sometimes these things get complicated! Production code is always longer!