How to Trap and Log Unexpected Errors in Batch Script
In a perfect script, every command would succeed. In reality, network shares go offline, files get locked by other users, and permissions are revoked. If your Batch script fails silently, it can lead to hours of wasted time trying to figure out why a backup didn't run or why a report is empty. "Trapping" errors involves detecting them the moment they happen and "Logging" them involves writing those details to a permanent file for later audit.
This guide will explain how to implement defensive error trapping and centralized logging.
1. The Immediate Trap Pattern
The most basic way to trap an error is to check the %errorlevel% variable immediately after a critical command.
@echo off
setlocal
set "LogFile=%~dp0error.log"
:: Attempt to create a directory
if not exist "C:\SecureData" mkdir "C:\SecureData"
:: Check for failure
if %errorlevel% neq 0 (
echo [%date% %time%] ERROR: Failed to create C:\SecureData. >> "%LogFile%"
echo [CRITICAL] Could not prepare workspace. See error.log.
endlocal
exit /b 1
)
2. Using Conditional Operators (Short-Hand Trapping)
If you don't want to write four lines of code for every command, you can use the || (OR) operator to trap errors on a single line.
@echo off
setlocal
set "Log=%~dp0audit.log"
:: Run the command; if it fails, the code after || executes
xcopy "C:\Source" "D:\Dest\" /E /I /Y >nul || (echo [%time%] Xcopy failed! >> "%Log%" & exit /b 1)
3. Centralized Error Handler (The Professional Way)
For larger scripts, jumping to a dedicated :ERROR_HANDLER label allows you to standardize how logs are written and how notifications are sent.
@echo off
setlocal
set "LOG_PATH=%~dp0system.log"
:: Task 1
net use Z: \\Server\Share >nul 2>&1
if %errorlevel% neq 0 (
set "ERR_MSG=MapDriveFailed"
goto :ERROR_LOGGER
)
:: Task 2
copy "Z:\data.csv" "C:\Local\" >nul 2>&1
if %errorlevel% neq 0 (
set "ERR_MSG=FileCopyFailed"
goto :ERROR_LOGGER
)
endlocal
exit /b 0
:ERROR_LOGGER
echo [%date% %time%] [FATAL] Code: %ERR_MSG% >> "%LOG_PATH%"
echo.
echo =========================================
echo ERROR DETECTED: %ERR_MSG%
echo Check %LOG_PATH% for details.
echo =========================================
endlocal
exit /b 1
How to Avoid Common Errors
Wrong Way: Redirecting all output to NUL
Using command >nul 2>&1 is great for clean looking scripts, but if the command fails, you have destroyed the exact error message (e.g., "Access Denied" vs "Disk Full") that you need for troubleshooting.
Correct Way: Only redirect >nul when you are sure you have a IF %errorlevel% check immediately after to capture the result.
Problem: Overwriting Logs
If you use echo msg > error.log, you delete your history.
Solution: Always use the double-arrow >> to append to the log file. This preserves your audit trail across multiple script runs.
Best Practices and Rules
1. Include the %USERNAME%
In corporate environments, knowing who was running the script when it failed is vital.
echo [%time%] User: %USERNAME% Error: %msg% >> log.txt
2. Standardized Log Format
Use a format that is easy to parse later (like CSV or YYYY-MM-DD). This allows you to open your log in Excel to filter for specific errors.
3. Log Successes Too
A "Progress Log" that shows [INFO] Started, [INFO] Midway, and [OK] Finished is often more helpful than a log that only shows errors, as it helps you identify exactly where a "Hang" occurred.
Conclusions
Trapping and logging errors is the primary difference between a script that works "sometimes" and a professional tool that works "everywhere." By proactively monitoring command outcomes and maintaining a persistent audit trail, you transform silent failures into actionable data. This resilience ensures that your automation is transparent, accountable, and significantly easier to maintain in complex IT environments.