Every scripting and programming language contains an error handler like Java contains try-catch
for error handling. In a Batch script, there is no direct way to do this, but we can create an error handler in the Batch script using a built-in variable of the Batch script name %ERRORLEVEL%
.
This article will show how we can create a Batch script to handle errors and failures. Also, we are going to some examples that make the topic easier.
Error Handling in Batch Script
When a command successfully executes, it always returns an EXIT CODE
that indicates whether the command successfully executed or failed to execute. So, to create an error handling in a Batch file, we can use that EXIT CODE
in our program.
You can follow below general format to create an error handler:
@Echo off
SomeCommand && (
ECHO Message for Success
) || (
ECHO Message for Failure or Error
)
We can also do that by checking the variable named %ERRORLEVEL%
. If the variable contains a value not equal to 0
, then there might be a problem or error when executing the command. To test the %ERRORLEVEL%
variable, you can follow the below example codes:
@ECHO off
Some Command Here !!!
IF %ERRORLEVEL% NEQ 0 (Echo Error found when running the command &Exit /b 1)
You must note that the keyword NEQ
means Not Equal. And the variable %ERRORLEVEL%
will only contain a non-zero value if there is a problem or error in the code.
An Example That Contains Errors
Below, we shared an example. We will run a Batch file named Your_file.bat
from a location.
We intentionally removed that file from the directory. So it’s an error command.
The code for our example will be:
@echo off
ECHO Running a Batch file
CD G:\BATCH\
CALL Your_file.bat
IF errorlevel 1 GOTO ERROR
ECHO The file run successfully.
GOTO EOF
:ERROR
ECHO The file didn't run successfully.
CMD /k
EXIT /b 1
:EOF
Now, as the file doesn’t exist in the directory, it will show an error, and you will get the below output when you run the code shared above.
Output:
Running a Batch file
The system cannot find the path specified.
'Your_file.bat' is not recognized as an internal or external command,
operable program or batch file.
The file didn't run successfully.
An Error-Free Code Example That Runs Successfully
In the example above, we made a mistake on the code intentionally to understand how the code works. If we correct it like below:
@echo off
ECHO Running a Batch file
CALL "G:\BATCH\Yourfile.bat"
IF errorlevel 1 GOTO ERROR
ECHO The file runs successfully.
GOTO EOF
:ERROR
ECHO The file didn't run successfully.
CMD /k
EXIT /b 1
:EOF
Then we will get an output like this:
Running a Batch file
This is from the first file
The file runs successfully.
Remember, all commands we discussed here are only for the Windows Command Prompt or CMD environment.
Эта статья рассказывает, какие возможности имеются в командном файле для привлечения внимания пользователя в случае какого-либо события или ошибки. Команды ECHO во многих случаях недостаточно, ведь это просто вывод текста, а хотелось бы, чтобы:
- уведомление было заметным пользователю, даже если он в это время работает в другой программе
- был удобный выбор для пользователя, какое действие bat файл должен сделать дальше
- информация была наглядной, например, чтобы была видна серьёзность события (ошибка или просто информация)
В современных решения пользовательского интерфейса Windows уведомление работает не так, что окно внезапно выскакивает поверх всех, прерывая работу пользователя, теперь происходит вежливое мигание значком программы или командного файла на панели задач. Поэтому пользователь может спокойно продолжить свою работу, например, закончить какой-то документ, а затем щелкнуть по значку и посмотреть, что же там случилось.
Поднять окно командного файла
Чтобы поднять наверх окно командного файла, можно использовать возможности WSH: скрипт activate.js использует метод WshShell.AppActivate для окна, заголовок которого передаётся параметром командной строки:
var title = WScript.Arguments.Unnamed(0); var wshshell = WScript.CreateObject("WScript.Shell"); wshshell.AppActivate(title);
Затем в командном файле устанавливаем заголовок окна и в нужный момент вызываем activate.js:
@echo off set window_title=Мой bat файл title %window_title% rem Здесь выполняются команды... if errorlevel 1 cscript //nologo activate.js "%window_title%" & pause
То есть если командный файл выполнился успешно, он тихо закрывается, не отвлекая пользователя. Если возникла ситуация, о которой нужно проинформировать пользователя, то окно поднимается наверх, показывая информацию об ошибке.
Этот скрипт можно переписать на VBScript.
Для наглядности будет полезно выделить цветом информацию о событии, например, об ошибке – красным цветом, о предупреждении – жёлтым и т.д..
Кроме этого, потребуется запрограммировать в bat файле выбор действия пользователем: с помощью pause для просто подтверждения, timeout для подтверждения с таймаутом или set /p для ввода значения.
В современных версиях Windows окно при выполнении этой команды окно не поднимается наверх, вместо этого начинает мигать значок на панели задач.
Показать всплывающее сообщение
Всплывающее сообщение MessageBox содержит текст со значком, это выглядит нагляднее, чем просто текст в консольном окне. Ещё в окне MessageBox могут быть различные сочетания кнопок (Да-Нет, ОК-Отмена и другие сочетания), с помощью которых пользователь может сделать свой выбор о выполняемых действиях.
Этот вариант использует возможности WSH и не требует установки дополнительных программ.
Используется метод WshShell.Popup в скрипте popup.js
var text = WScript.Arguments.Unnamed(0); var title = WScript.Arguments.Unnamed(1); var wshshell = WScript.CreateObject("WScript.Shell"); wshshell.Popup(text,0,title,16);
Соответственно, командный файл вызывает его в случае ошибки:
cscript //nologo popup.js "Сбой процедуры полного резервного копирования. Сервер недоступен." "Резервное копирование"
Всплывающее окно NHMB
Программа nhmb также показывает всплывающее окно с выбором значка и кнопок, с возможностью задавать символы перевода строки, а также с отображением таймера в заголовке окна.
nhmb.exe "Сбой процедуры полного резервного копирования.\nСервер недоступен." "Резервное копирование" error 60
В заголовке окна отображается время в секундах (55), оставшееся до автоматического закрытия окна и продолжения работы командного файла.
Все параметры всплывающего окна задаются в командной строке, и для удобства на странице программы есть генератор строки запуска, который формирует всю строку по требуемым условиям – нет необходимости разбираться в справке и тестировать команды, достаточно выбрать желаемое отображение и скопировать готовую строку в свой bat файл.
Сравнение
Скрипт AppActivate | Скрипт Popup | Программа nhmb | |
---|---|---|---|
Значок | нет | да | да |
Заголовок | нет | да | да |
Сообщение в несколько строк | да | да | да |
Команды с простым выбором | нет | да | да |
Команда по умолчанию с таймером | нет | есть, но таймер не отображается | есть, таймер отображается |
Требуется программирование | да | да | нет |
Узнать больше
Файлы для скачивания
Наши соцсети
i have a oracle sqldeveloper file.
when i run it by using a batch file, if it encounter an error, the cmd will surely display the error.
what i want is, is it possible to take the cmd error as an input to trigger out my custom made error message??
if in cmd displaying any error for example:
Parameter not found
my custom-made error message in batch file will triggered out this error message in the cmd:
You Got An Error!
any help and suggestions are appreciated..
Thanks in advance!
asked Dec 2, 2011 at 6:59
2
You can redirect the output (both stdout and stderr) to a text file (or to nul
if you don’t care about the output), and check the value of `%ERRORLEVEL% after your script has been executed. If it is not 0, then display your own error message.
To redirect both stdout and stderr:
command parameters 1>>c:\log.txt 2>&1
answered Dec 2, 2011 at 16:40
LafLaf
7,9854 gold badges37 silver badges52 bronze badges
2
I recommend using SQL*Plus instead of SQL Developer. You can add WHENEVER SQLERROR EXIT FAILURE to the top of the script (or EXIT SQL.SQLCODE if you are interested in the specific error code). Then the calling batch file will receive the error code in %ERRORLEVEL% and you can take action appropriately. There is also WHENEVER OSERROR EXIT FAILURE if your SQL script interfaces with the OS with the potential of failure there.
I don’t think SQL*Plus uses stderr, so I don’t think you need to worry about redirecting 2>&1.
answered Dec 4, 2011 at 6:19
dbenhamdbenham
128k28 gold badges253 silver badges391 bronze badges
- Overview
- Part 1 – Getting Started
- Part 2 – Variables
- Part 3 – Return Codes
- Part 4 – stdin, stdout, stderr
- Part 5 – If/Then Conditionals
- Part 6 – Loops
- Part 7 – Functions
- Part 8 – Parsing Input
- Part 9 – Logging
- Part 10 – Advanced Tricks
Today we’ll cover return codes as the right way to communicate the outcome of your script’s execution to the world. Sadly, even
skilled Windows programmers overlook the importance of return codes.
Return Code Conventions
By convention, command line execution should return zero when execution succeeds and non-zero when execution fails. Warning messages
typically don’t effect the return code. What matters is did the script work or not?
Checking Return Codes In Your Script Commands
The environmental variable %ERRORLEVEL%
contains the return code of the last executed program or script. A very helpful feature is
the built-in DOS commands like ECHO
, IF
, and SET
will preserve the existing value of %ERRORLEVEL%
.
The conventional technique to check for a non-zero return code using the NEQ
(Not-Equal-To) operator of the IF
command:
IF %ERRORLEVEL% NEQ 0 (
REM do something here to address the error
)
Another common technique is:
IF ERRORLEVEL 1 (
REM do something here to address the error
)
The ERRORLEVEL 1
statement is true when the return code is any number equal to or greater than 1. However, I don’t use this technique because
programs can return negative numbers as well as positive numbers. Most programs rarely document every possible return code, so I’d rather explicity
check for non-zero with the NEQ 0
style than assuming return codes will be 1 or greater on error.
You may also want to check for specific error codes. For example, you can test that an executable program or script is in your PATH by simply
calling the program and checking for return code 9009.
SomeFile.exe
IF %ERRORLEVEL% EQU 9009 (
ECHO error - SomeFile.exe not found in your PATH
)
It’s hard to know this stuff upfront – I generally just use trial and error to figure out the best way to check the return code of the program or
script I’m calling. Remember, this is duct tape programming. It isn’t always pretty, but, it gets the job done.
Conditional Execution Using the Return Code
There’s a super cool shorthand you can use to execute a second command based on the success or failure of a command. The first program/script must
conform to the convention of returning 0 on success and non-0 on failure for this to work.
To execute a follow-on command after sucess, we use the &&
operator:
SomeCommand.exe && ECHO SomeCommand.exe succeeded!
To execute a follow-on command after failure, we use the ||
operator:
SomeCommand.exe || ECHO SomeCommand.exe failed with return code %ERRORLEVEL%
I use this technique heavily to halt a script when any error is encountered. By default, the command processor will continue executing
when an error is raised. You have to code for halting on error.
A very simple way to halt on error is to use the EXIT
command with the /B
switch (to exit the current batch script context, and not the command
prompt process). We also pass a specific non-zero return code from the failed command to inform the caller of our script about the failure.
SomeCommand.exe || EXIT /B 1
A simliar technique uses the implicit GOTO label called :EOF
(End-Of-File). Jumping to EOF in this way will exit your current script with
the return code of 1.
SomeCommand.exe || GOTO :EOF
Tips and Tricks for Return Codes
I recommend sticking to zero for success and return codes that are positive values for DOS batch files. The positive values are a good idea
because other callers may use the IF ERRORLEVEL 1
syntax to check your script.
I also recommend documenting your possible return codes with easy to read SET
statements at the top of your script file, like this:
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
Note that I break my own convention here and use uppercase variable names – I do this to denote that the variable is constant and should not
be modified elsewhere. Too bad DOS doesn’t support constant values like Unix/Linux shells.
Some Final Polish
One small piece of polish I like is using return codes that are a power of 2.
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
SET /A ERROR_FILE_READ_ONLY=4
SET /A ERROR_UNKNOWN=8
This gives me the flexibility to bitwise OR multiple error numbers together if I want to record numerous problems in one error code.
This is rare for scripts intended for interactive use, but, it can be super helpful when writing scripts you support but you don’t
have access to the target systems.
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SET /A errno=0
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_SOMECOMMAND_NOT_FOUND=2
SET /A ERROR_OTHERCOMMAND_FAILED=4
SomeCommand.exe
IF %ERRORLEVEL% NEQ 0 SET /A errno^|=%ERROR_SOMECOMMAND_NOT_FOUND%
OtherCommand.exe
IF %ERRORLEVEL% NEQ 0 (
SET /A errno^|=%ERROR_OTHERCOMMAND_FAILED%
)
EXIT /B %errno%
If both SomeCommand.exe and OtherCommand.exe fail, the return code will be the bitwise combination of 0x1 and 0x2, or decimal 3. This return code tells
me that both errors were raised. Even better, I can repeatedly call the bitwise OR with the same error code and still interpret which errors were
raised.
<< Part 2 – Variables
Part 4 – stdin, stdout, stderr >>
- SS64
- CMD
- How-to
Errorlevel and Exit codes
Almost all applications and utilities will set an Exit Code when they complete/terminate.
The exit codes that are set do vary, in general a code of 0 (false) will indicate successful completion.
By default SCCM will only consider 0 a success, but commands like Robocopy may return success Exit Codes from 0 to 7.
The exit codes set by resource kit utilities are not always consistent, they can vary between machines with different Service packs/Resource kit updates applied. Some utilities will return negative numbers as an exit code.
If you attempt to execute a non-existent command %ERRORLEVEL% will be set to 9009
Detecting Errorlevels
There are two different methods of checking an errorlevel, the first syntax provides compatibility with old .bat batch files from the era of MS-DOS
The errorlevel is made available via IF ERRORLEVEL … or the %ERRORLEVEL% variable.
IF ERRORLEVEL n statements should be read as IF Errorlevel >= number
i.e.
IF ERRORLEVEL 0 will return TRUE whether the errorlevel is 0, 1 or 5 or 64
IF ERRORLEVEL 1 will return TRUE whether the errorlevel is 1 or 5 or 64
IF NOT ERRORLEVEL 3 means if ERRORLEVEL is less than 3 ( 2, 1, 0 or a negative number).To check for a specific error level N, you can use the following construct:
IF ERRORLEVEL N IF NOT ERRORLEVEL N+1 COMMAND
This is not very readable or user friendly and does not account for negative error numbers.
A preferred method of checking Errorlevels is to use the %ERRORLEVEL% pseudo variable:
IF %ERRORLEVEL% NEQ 0 Echo An error was found
IF %ERRORLEVEL% EQU 0 Echo No error foundIF %ERRORLEVEL% EQU 0 (Echo No error found) ELSE (Echo An error was found)
IF %ERRORLEVEL% EQU 0 Echo No error found || Echo An error was foundThis allows you to trap errors that can be negative numbers, you can also test for specific errors:
IF %ERRORLEVEL% EQU 64 …When ending a subroutine, you can use EXIT /b N to set a specific ERRORLEVEL N.
Raymond Chen [MSFT] explains: ERRORLEVEL is not the same as the %ERRORLEVEL% environment variable.
Error Message/Error Stream
In addition to setting an ERRORLEVEL, many utilities will output an error message on the error stream (STDERR), by default these messages will appear on the console, but they can be redirected with 2>.
Many utilities set an ERRORLEVEL and also output some error text, some utilities set an ERRORLEVEL but don’t display error text and some will display error text without setting an ERRORLEVEL. Some utilities behave differently depending on the severity of the error.
Error messages are likely to be different for each language/locale so it is generally more robust to just test the ERRORLEVEL rather than any text message output.
Error level vs Exit code
When an external command is run by CMD.EXE, it will detect the executable’s Return or Exit Code and set the %ERRORLEVEL% to match.
In the majority of cases command extensions are enabled and so the %ERRORLEVEL% will be the same as the Exit code. It is possible to break this by manually creating a user variable called %ERRORLEVEL%.An Exit Code can be detected directly with redirection operators Success=0 or Failure<>0. This is equivalent to IF ERRORLEVEL 1.
Old style .bat Batch files vs .cmd Batch scripts.
Although the differences are minor, there are no advantages to the .BAT extension, so I recommend using .CMD exclusively.
There is a key difference between the way .CMD and .BAT batch files set errorlevels:
A .CMD batch script will set/reset the ERRORLEVEL after every command that you run [source] Mark Zbikowski (MSFT).
A .BAT batch script running the internal commands: APPEND, ASSOC, PATH, PROMPT, FTYPE and SET will only change the ERRORLEVEL if an error occurs. Other internal and external commands do not follow this rule.
So if you have two commands in a .BAT script and the first command fails but the second succeeds, the ERRORLEVEL may or may not remain set depending on which command was run.
This lack of consistency in the ERRORLEVELs raised makes debugging a .BAT script more difficult than an equlvalent .CMD script.
Even in the CMD shell, some commands don’t follow the rules
Even though a CMD batch script should set or reset ERRORLEVEL after every command, there are a few exceptions:
Commands that do NOT affect the ERRORLEVEL:
BREAK, ECHO, ENDLOCAL, FOR, IF, PAUSE, REM, RD/RMDIR, TITLECommands that will set but not clear an ERRORLEVEL:
CLS, GOTO, KEYS, POPD, SHIFTCommands that set an Exit Code but not the ERRORLEVEL:
RD/RMDIRCommands that set an ERRORLEVEL but not the Exit Code (SO explanation):
MD/MKDIR
Set or Force an exit code
You can make a batch file return a non-zero exit code by using the EXIT command.
Exit 0
Exit /B 5To force an ERRORLEVEL of 1 to be set without exiting, run a small but invalid command like COLOR 00 or run (CALL) which does nothing other than set the ERRORLEVEL to 1.
To clear the ERRORLEVEL back to 0, run (call ), which does nothing except set the ERRORLEVEL to 0.
You should never attempt to SET the %ERRORLEVEL% because that will create a user variable named %ERRORLEVEL% which then takes precedence over the internal pseudo variable %ERRORLEVEL%.
You can clear any such user variable with the following command but really the best practice is to never set a variable with that name in the first place:
Set «errorlevel=»
PowerShell
In PowerShell $? contains True if last operation succeeded and False otherwise.
The exit code of the last Win32 executable execution is stored in the automatic variable $LASTEXITCODE
To read exit codes (other than 0 or 1) launch the PowerShell script and return the $LASTEXITCODE in a single line like this:
powershell.exe -noprofile C:\scripts\script.ps1; exit $LASTEXITCODE
“I’d rather wake up in the middle of nowhere than in any city on earth” ~ Steve McQueen
Related commands
Robocopy exit codes
Conditional Execution — if command1 succeeds then execute command2
HowTo: Error Handling in a batch file
List of ERRORLEVEL values set by internal cmd.exe commands — Stackoverflow /Aacini.
ERRORLEVEL is not %ERRORLEVEL% — The old new thing blog.
Copyright © 1999-2023 SS64.com
Some rights reserved