Синтаксис обработки исключений - Exception handling syntax
Синтаксис обработки исключений - это набор ключевых слов и / или структур, предоставляемых языком программирования для разрешения обработки исключений , который отделяет обработку ошибок, возникающих во время работы программы, от ее обычных процессов. Синтаксис для обработки исключений варьируется в зависимости от языка программирования , частично для того, чтобы покрыть семантические различия, но в значительной степени для того, чтобы вписаться в общую синтаксическую структуру каждого языка . Некоторые языки не называют соответствующую концепцию « обработкой исключений »; другие могут не иметь для этого прямых возможностей, но все же могут предоставить средства для его реализации.
Чаще всего для обработки ошибок используется try...[catch...][finally...]
блок, а ошибки создаются с помощью throw
оператора, но существуют значительные различия в именах и синтаксисе.
Каталог синтаксисов обработки исключений
Ада
- Объявления исключений
Some_Error : exception;
- Вызов исключений
raise Some_Error;
raise Some_Error with "Out of memory"; -- specific diagnostic message
- Обработка и распространение исключений
with Ada.Exceptions, Ada.Text_IO;
procedure Foo is
Some_Error : exception;
begin
Do_Something_Interesting;
exception -- Start of exception handlers
when Constraint_Error =>
... -- Handle constraint error
when Storage_Error =>
-- Propagate Storage_Error as a different exception with a useful message
raise Some_Error with "Out of memory";
when Error : others =>
-- Handle all others
Ada.Text_IO.Put("Exception: ");
Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Name(Error));
Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Message(Error));
end Foo;
язык ассемблера
Большинство языков ассемблера будут иметь макро-инструкцию или адрес прерывания, доступный для конкретной системы, чтобы перехватывать такие события, как недопустимые коды операций, проверка программы, ошибки данных, переполнение, деление на ноль и другие подобные. В мэйнфреймах IBM и Univac был макрос STXIT . В системах RT11 компании Digital Equipment Corporation были векторы ловушек для программных ошибок, прерываний ввода-вывода и т. Д. DOS имеет определенные адреса прерывания. В Microsoft Windows есть специальные вызовы модулей для перехвата программных ошибок.
Баш
#!/usr/bin/env bash
#set -e provides another error mechanism
print_error(){
echo "there was an error"
}
trap print_error exit #list signals to trap
tempfile=`mktemp`
trap "rm $tempfile" exit
./other.sh || echo warning: other failed
echo oops)
echo never printed
Можно установить ловушку для множественных ошибок, отвечая на любой сигнал синтаксисом типа:
trap 'echo Error at line ${LINENO}' ERR
БАЗОВЫЙ
On Error Гото / GoSub структура используется в BASIC и довольно сильно отличается от современной обработки исключений; в BASIC есть только один глобальный обработчик, тогда как в современной обработке исключений обработчики исключений складываются.
ON ERROR GOTO handler
OPEN "Somefile.txt" FOR INPUT AS #1
CLOSE #1
PRINT "File opened successfully"
END
handler:
PRINT "File does not exist"
END ' RESUME may be used instead which returns control to original position.
C
C не обеспечивает прямой поддержки обработки исключений: программист обязан в первую очередь предотвращать ошибки и проверять возвращаемые значения функций.
В любом случае возможный способ реализовать обработку исключений в стандарте C - использовать функции setjmp / longjmp :
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
enum { SOME_EXCEPTION = 1 } exception;
jmp_buf state;
int main(void)
{
if (!setjmp(state)) // try
{
if (/* something happened */)
{
exception = SOME_EXCEPTION;
longjmp(state, 0); // throw SOME_EXCEPTION
}
}
else switch(exception)
{
case SOME_EXCEPTION: // catch SOME_EXCEPTION
puts("SOME_EXCEPTION caught");
break;
default: // catch ...
puts("Some strange exception");
}
return EXIT_SUCCESS;
}
Специально для Microsoft
Существуют два типа:
- Структурированная обработка исключений (SEH)
- Векторная обработка исключений (VEH, представленная в Windows XP )
Пример SEH на языке программирования C:
int filterExpression (EXCEPTION_POINTERS* ep) {
ep->ContextRecord->Eip += 8; // divide instruction may be encoded from 2 to 8 bytes
return EXCEPTION_CONTINUE_EXECUTION;
}
int main(void) {
static int zero;
__try {
zero = 1/zero;
__asm {
nop
nop
nop
nop
nop
nop
nop
}
printf ("Past the exception.\n");
} __except (filterExpression (GetExceptionInformation())) {
printf ("Handler called.\n");
}
return 0;
}
C #
В try
блоке должно быть хотя бы одно предложение catch
или finally
и не более одного finally
предложения.
public static void Main()
{
try
{
// Code that could throw an exception.
}
catch (HttpException ex)
{
// Handles a HttpException. The exception object is stored in "ex".
}
catch (Exception)
{
// Handles any CLR exception that is not a HttpException.
// Since the exception has not been given an identifier, it cannot be referenced.
}
catch
{
// Handles anything that might be thrown, including non-CLR exceptions.
}
finally
{
// Always run when leaving the try block (including catch clauses), regardless of whether any exceptions were thrown or whether they were handled.
// Often used to clean up and close resources such a file handles.
// May not be run when Environment.FailFast() is called and in other system-wide exceptional conditions (e.g. power loss), or when the process crashes due to an exception in another thread.
}
}
C ++
#include <exception>
int main() {
try {
// do something (might throw an exception)
}
catch (const std::exception& e) {
// handle exception e
}
catch (...) {
// catches all exceptions, not already caught by a catch block before
// can be used to catch exception of unknown or irrelevant type
}
}
В C ++ получение ресурсов - это метод инициализации , который может использоваться для очистки ресурсов в исключительных ситуациях. C ++ намеренно не поддерживает finally
. Внешние скобки для метода не являются обязательными.
Язык разметки ColdFusion (CFML)
Синтаксис скрипта
<cfscript>
try {
//throw CF9+
throw(type="TypeOfException", message="Oops", detail="xyz");
// alternate throw syntax:
throw "Oops"; // this equivalent to the "message" value in the above example
} catch (any e) {
writeOutput("Error: " & e.message);
rethrow; //CF9+
} finally { //CF9+
writeOutput("I run even if no error");
}
</cfscript>
Документация Adobe ColdFusion
Синтаксис тега
<cftry>
code that may cause an exception
<cfcatch ...>
<cftry>
First level of exception handling code
<cfcatch ...>
Second level of exception handling code
</cfcatch>
<cffinally>
final code
</cffinally>
</cftry>
</cfcatch>
</cftry>
Документация Adobe ColdFusion
Специфический синтаксис Railo-Lucee
В дополнение к стандартному синтаксису выше, CFML диалекты Railo и Lucee позволяют retry
заявление.
Этот оператор возвращает обработку к началу предыдущего try
блока.
Пример CFScript:
try {
// code which could result in an exception
} catch (any e){
retry;
}
Пример синтаксиса тега:
<cftry>
<!--- code which could result in an exception --->
<cfcatch>
<cfretry>
</cfcatch>
</cftry>
D
import std.stdio; // for writefln()
int main() {
try {
// do something that might throw an exception
}
catch (FooException e) {
// handle exceptions of type FooException
}
catch (Object o) {
// handle any other exceptions
writefln("Unhandled exception: ", o);
return 1;
}
return 0;
}
В D finally
предложение или метод инициализации получения ресурсов может использоваться для очистки ресурсов в исключительных ситуациях.
Delphi
- Объявления исключений
type ECustom = class(Exception) // Exceptions are children of the class Exception.
private
FCustomData: SomeType; // Exceptions may have custom extensions.
public
constructor CreateCustom(Data: SomeType); // Needs an implementation
property CustomData: SomeType read FCustomData;
end;
- Вызов исключений
raise Exception.Create('Message');
raise Exception.CreateFmt('Message with values: %d, %d',[value1, value2]); // See SysUtils.Format() for parameters.
raise ECustom.CreateCustom(X);
- Обработка и распространение исключений
try // For finally.
try // For except.
... // Code that may raise an exception.
except
on C:ECustom do
begin
... // Handle ECustom.
... if Predicate(C.CustomData) then ...
end;
on S:ESomeOtherException do
begin
// Propagate as an other exception.
raise EYetAnotherException.Create(S.Message);
end;
on E:Exception do
begin
... // Handle other exceptions.
raise; // Propagate.
end;
end;
finally
// Code to execute whether or not an exception is raised (e.g., clean-up code).
end;
Erlang
try
% some dangerous code
catch
throw:{someError, X} -> ok; % handle an exception
error:X -> ok; % handle another exception
_:_ -> ok % handle all exceptions
after
% clean up
end
F #
В дополнение к основанной на OCaml try...with
, F # также имеет отдельную try...finally
конструкцию, которая имеет то же поведение, что и блок try с finally
предложением на других языках .NET.
Для сравнения, это перевод приведенного выше примера C # .
try
try
() (* Code that could throw an exception. *)
with
| :? System.Net.WebException as ex -> () (* Handles a WebException. The exception object is stored in "ex". *)
| :? exn -> () (* Handles any CLR exception. Since the exception has not been given an identifier, it cannot be referenced. *)
| _ -> () (* Handles anything that might be thrown, including non-CLR exceptions. *)
finally
()
(*
Always run when leaving the try block, regardless of whether any exceptions were thrown or whether they were handled.
Often used to clean up and close resources such a file handles.
May not be run when Environment.FailFast() is called and in other system-wide exceptional conditions (e.g. power loss), or when the process crashes due to an exception in another thread.
*)
Для сравнения это перевод примера OCaml ниже .
exception MyException of string * int (* exceptions can carry a value *)
let _ =
try
raise (MyException ("not enough food", 2));
printfn "Not reached"
with
| MyException (s, i) ->
printf "MyException: %s, %d\n" s i
| e -> (* catch all exceptions *)
eprintf "Unexpected exception : %O" e;
eprintf "%O" e.StackTrace
Haskell
В Haskell нет специального синтаксиса для исключений. Вместо этого try
/ catch
/ finally
/ etc
. интерфейс предоставляется функциями.
import Prelude hiding(catch)
import Control.Exception
instance Exception Int
instance Exception Double
main = do
catch
(catch
(throw (42::Int))
(\e-> print (0,e::Double)))
(\e-> print (1,e::Int))
отпечатки
(1,42)
по аналогии с этим C ++
#include <iostream>
using namespace std;
int main()
{
try
{throw (int)42;}
catch(double e)
{cout << "(0," << e << ")" << endl;}
catch(int e)
{cout << "(1," << e << ")" << endl;}
}
Другой пример
do {
-- Statements in which errors might be thrown
} `catch` \ex -> do {
-- Statements that execute in the event of an exception, with 'ex' bound to the exception
}
В чисто функциональном коде, если только одно условие ошибки существует, Maybe
тип может быть достаточно, и является экземпляром Хаскеля Monad
класса по умолчанию. Более сложное распространение ошибок может быть достигнуто с помощью монад Error
или ErrorT
, для которых поддерживается аналогичная функциональность (использование ).
`catch`
Джава
В try
блоке должно быть хотя бы одно предложение catch
или finally
и не более одного finally
предложения.
try {
// Normal execution path.
throw new EmptyStackException();
} catch (ExampleException ee) {
// Deal with the ExampleException.
} finally {
// Always run when leaving the try block (including finally clauses), regardless of whether any exceptions were thrown or whether they were handled.
// Often used to clean up and close resources such a file handles.
// May no be run when System.exit() is called and in other system-wide exceptional conditions (e.g. power loss).
}
JavaScript
Дизайн JavaScript очень редко допускает громкие / серьезные ошибки. Мягкие / тихие ошибки гораздо более распространены. Серьезные ошибки распространяются на ближайший try
оператор, за которым должно следовать либо одно catch
предложение, либо одно finally
предложение, либо оба предложения.
try {
// Statements in which exceptions might be thrown
throw new Error("error");
} catch(error) {
// Statements that execute in the event of an exception
} finally {
// Statements that execute afterward either way
}
Если нет никакого try
заявления, тогда веб-страница не вылетает. Вместо этого в консоль регистрируется ошибка, и стек очищается. Однако у JavaScript есть интересная особенность асинхронных точек входа, вызываемых извне. В то время как в большинстве других языков некоторая часть кода всегда выполняется постоянно, JavaScript не обязательно должен выполняться линейно от начала до конца. Например, прослушиватели событий, обещания и таймеры могут быть вызваны браузером в более поздний момент времени и запущены в изолированном, но общем контексте с остальной частью кода. Обратите внимание, как приведенный ниже код будет выдавать новую ошибку каждые 4 секунды в течение неопределенного периода времени или до тех пор, пока браузер / вкладка / компьютер не будут закрыты.
setInterval(function() {
throw new Error("Example of an error thrown on a 4 second interval.");
}, 4000);
Еще одна интересная особенность - полиморфизм: JavaScript может выдавать примитивные значения как ошибки.
try {
throw 12345; // primitive number
} catch(error) {
console.log(error); // logs 12345 as a primitive number to the console
}
Обратите внимание, что это catch
предложение является универсальным, в нем учитываются все типы ошибок. Нет синтаксической возможности назначать разные обработчики для разных типов ошибок, кроме экспериментальных и удаленных в настоящее время расширений Gecko много лет назад. Вместо этого можно либо распространить ошибку, используя throw
оператор внутри catch
оператора, либо использовать несколько условных случаев. Давайте сравним пример на Java и его приблизительные эквиваленты на JavaScript.
// Example in Java
try {
Integer i = null;
i.intValue(); // throws a NullPointerException
} catch(NullPointerException error) {
// Variable might be null
} catch(ArithmeticException error) {
// Handle problems with numbers
}
// Approximation #1 in JavaScript
try {
// Statements in which exceptions might be thrown
var example = null;
example.toString();
} catch(error) {
if (error.type === "TypeError") {
// Variable might be null
} else if (error.type === "RangeError") {
// Handle problems with numbers
}
}
// Approximation #2 in JavaScript
try {
try {
// Statements in which exceptions might be thrown
var example = null;
example.toString();
} catch(error) {
if (error.type !== "TypeError") throw error;
// Variable might be null
}
} catch(error) {
if (error.type !== "RangeError") throw error;
// Handle problems with numbers
}
Другой аспект исключений - это обещания, которые обрабатывают исключение асинхронно. Асинхронная обработка исключения имеет то преимущество, что ошибки внутри обработчика ошибок не распространяются дальше вовне.
new Promise(function() {
throw new Error("Example error!");
}).catch(function(err) {
console.log("Caught ", err);
});
Также обратите внимание, как обработчики событий могут быть связаны с обещаниями.
addEventListener("unhandledrejection", function(event) {
console.log(event.reason);
event.preventDefault(); //prevent logging the error via console.error to the console--the default behavior
});
new Promise(function() {
throw new Error("Example error!");
});
Наконец, обратите внимание, что, поскольку JavaScript использует сборку мусора mark-and-sweep, никогда не происходит утечки памяти из-за операторов throw, потому что браузер автоматически очищает мертвые объекты - даже с циклическими ссылками.
try {
// Statements in which exceptions might be thrown
const obj = {};
obj.selfPropExample = obj; // circular reference
throw obj;
} catch(error) {
// Statements that execute in the event of an exception
}
Лисп
Common Lisp
(ignore-errors (/ 1 0))
(handler-case
(progn
(print "enter an expression")
(eval (read)))
(error (e) (print e)))
(unwind-protect
(progn
(print "enter an expression")
(eval (read)))
(print "This print will always be executed, similar to finally."))
Lua
Lua использует pcall
и xpcall
функции, с xpcall
принимая функцию , чтобы действовать в качестве catch
блока.
- Предопределенная функция
function foo(x)
if x then
return x
else
error "Not a true value"
end
end
function attempt(arg)
success, value = pcall(foo, arg)
if not success then
print("Error: " .. tostring(value))
else
print("Returned: " .. tostring(value))
end
end
attempt("hello")
-- Returned: hello
attempt(nil)
-- Error: stdin:5: Not a true value
attempt({})
-- Returned: table: 00809308
if foo(42) then print "Success" end
-- Success
- Анонимная функция
if pcall(
function()
-- Do something that might throw an error.
end)
then
print "No errors" -- Executed if the protected call was successful.
else
print "Error encountered" -- Executed if the protected call failed.
end
print "Done" -- Will always be executed
Оболочка нового поколения
- Определение настраиваемого типа исключения
type MyError(Error)
- Вызов исключений
throw MyError("this happened")
- Обработка и распространение исключений
try {
# something
} catch(e:MyError) {
guard e.val = 7
# ...
} catch(e:MyError) {
# ...
} catch(e:Error) {
# ...
}
- Игнорирование исключений - попробуйте без уловки
try 1/0 # evaluates to null
- Игнорирование исключений - оператор "tor"
"tor" - это оператор try-or. В случае какого-либо исключения при оценке аргумента слева оценивается аргумент справа.
1/0 tor 20 # evaluates to 20
- «блок» - возможность использовать исключения для возврата значения
my_result = block my_block { # "block" catches exception thrown by return below
# do calculation
if calculation_finished() {
my_block.return(42) # throws exception
}
}
Цель-C
- Объявления исключений
NSException *exception = [NSException exceptionWithName:@"myException"
reason:@"whatever" userInfo:nil];
- Вызов исключений
@throw exception;
- Обработка и распространение исключений
@try {
...
}
@catch (SomeException *se) {
// Handle a specific exception type.
...
}
@catch (NSException *ne) {
// Handle general exceptions.
...
// Propagate the exception so that it's handled at a higher level.
@throw;
}
@catch (id ue) {
// Catch all thrown objects.
...
}
@finally {
// Perform cleanup, whether an exception occurred or not.
...
}
OCaml
exception MyException of string * int (* exceptions can carry a value *)
let _ =
try
raise (MyException ("not enough food", 2));
print_endline "Not reached"
with
| MyException (s, i) ->
Printf.printf "MyException: %s, %d\n" s i
| e -> (* catch all exceptions *)
Printf.eprintf "Unexpected exception : %s" (Printexc.to_string e);
(*If using Ocaml >= 3.11, it is possible to also print a backtrace: *)
Printexc.print_backtrace stderr;
(* Needs to beforehand enable backtrace recording with
Printexc.record_backtrace true
or by setting the environment variable OCAMLRUNPARAM="b1"*)
Perl 5
Механизм Perl для обработки исключений использует die
для создания исключения при заключении в блок. После , специальная переменная содержит значение, переданное из . Однако проблемы с областью видимости могут сделать это правильно довольно некрасивым:
eval { ... };
eval
$@
die
my ($error, $failed);
{
local $@;
$failed = not eval {
# Code that could throw an exception (using 'die')
open(FILE, $file) || die "Could not open file: $!";
while (<FILE>) {
process_line($_);
}
close(FILE) || die "Could not close $file: $!";
return 1;
};
$error = $@;
}
if ($failed) {
warn "got error: $error";
}
Perl 5.005 добавил возможность бросать объекты, а также строки. Это позволяет лучше анализировать и обрабатывать типы исключений.
eval {
open(FILE, $file) || die MyException::File->new($!);
while (<FILE>) {
process_line($_);
}
close(FILE) || die MyException::File->new($!);
};
if ($@) {
# The exception object is in $@
if ($@->isa('MyException::File')) {
# Handle file exception
} else {
# Generic exception handling
# or re-throw with 'die $@'
}
}
__DIE__
Псевдо-сигнал может задерживаться для обработки вызовов в die
. Это не подходит для обработки исключений, поскольку является глобальным. Однако его можно использовать для преобразования исключений на основе строк из сторонних пакетов в объекты.
local $SIG{__DIE__} = sub {
my $err = shift;
if ($err->isa('MyException')) {
die $err; # re-throw
} else {
# Otherwise construct a MyException with $err as a string
die MyException::Default->new($err);
}
};
Формы, показанные выше, могут иногда терпеть неудачу, если глобальная переменная $@
изменяется между моментом, когда возникает исключение, и тем, когда она проверяется в инструкции. Это может происходить в многопоточных средах или даже в однопоточных средах, когда другой код (обычно вызываемый при уничтожении какого-либо объекта) сбрасывает глобальную переменную перед кодом проверки. Следующий пример показывает способ избежать этой проблемы (см. [1] или [2] ; ср . [3] ). Но ценой невозможности использовать возвращаемые значения:
if ($@)
eval {
# Code that could throw an exception (using 'die') but does NOT use the return statement;
1;
} or do {
# Handle exception here. The exception string is in $@
};
Несколько модулей в Comprehensive Perl Archive Network ( CPAN ) расширяют базовый механизм:
-
Error
предоставляет набор классов исключений и позволяет использовать синтаксис try / throw / catch / finally. -
TryCatch
и оба позволяют использовать синтаксис try / catch / finally вместо стандартного для правильной обработки исключений.Try::Tiny
-
Exception::Class
является базовым классом и создателем классов для производных классов исключений. Она обеспечивает полный структурированный трассировки стека в и .$@->trace
$@->trace->as_string
-
Fatal
Перегрузки ранее определенные функции , которые возвращают истина / ложь , например,open
,close
,read
,write
и т.д. Это позволяет встроенные функции и другие , которые будут использоваться , как если бы они бросили исключения.
PHP
// Exception handling is only available in PHP versions 5 and greater.
try {
// Code that might throw an exception
throw new Exception('Invalid URL.');
} catch (FirstExceptionClass $exception) {
// Code that handles this exception
} catch (SecondExceptionClass $exception) {
// Code that handles a different exception
} finally {
// Perform cleanup, whether an exception occurred or not.
}
PowerBuilder
Обработка исключений доступна в PowerBuilder версии 8.0 и выше.
TRY // Normal execution path CATCH (ExampleException ee) // deal with the ExampleException FINALLY // This optional section is executed upon termination of any of the try or catch blocks above END TRY
PowerShell
Версия 1.0
trap [Exception]
{
# Statements that execute in the event of an exception
}
# Statements in which exceptions might be thrown
Версия 2.0
Try {
Import-Module ActiveDirectory
}
Catch [Exception1] {
# Statements that execute in the event of an exception, matching the exception
}
Catch [Exception2],[Exception3etc] {
# Statements that execute in the event of an exception, matching any of the exceptions
}
Catch {
# Statements that execute in the event of an exception, not handled more specifically
}
Python
f = None
try:
f = open("aFileName", "w")
f.write(could_make_error())
except IOError:
print("Unable to open file")
except: # catch all exceptions
print("Unexpected error")
else: # executed if no exceptions are raised
print("File write completed successfully")
finally: # clean-up actions, always executed
if f:
f.close()
р
tryCatch({
stop("Here an error is signaled") # default S3-class is simpleError a subclass of error
cat("This and the following lines are not executed because the error is trapped before\n")
stop( structure(simpleError("mySpecialError message"),class=c("specialError","error","condition")) )
}
,specialError=function(e){
cat("catches errors of class specialError\n")
}
,error=function(e){
cat("catches the default error\n")
}
,finally={ cat("do some cleanup (e.g., setwd)\n") }
)
Ребол
REBOL [
Title: "Exception and error handling examples"
]
; TRY a block; capturing an error! and converting to object!
if error? exception: try [1 / 0][probe disarm exception]
; ATTEMPT results in the value of the block or the value none on error
print attempt [divide 1 0]
; User generated exceptions can be any datatype!
example: func ["A function to throw an exception"
][
throw "I'm a string! exception"
]
catch [example]
; User generated exceptions can also be named,
; and functions can include additional run time attributes
sophisticated: func ["A function to throw a named error exception"
[catch]
][
throw/name make error! "I'm an error! exception" 'moniker
]
catch/name [sophisticated] 'moniker
Rexx
signal on halt;
do a = 1
say a
do 100000 /* a delay */
end
end
halt:
say "The program was stopped by the user"
exit
Рубин
begin
# Do something nifty
raise SomeError, "This is the error message!" # Uh-oh!
rescue SomeError
# This is executed when a SomeError exception
# is raised
rescue AnotherError => error
# Here, the exception object is referenced from the
# `error' variable
rescue
# This catches all exceptions derived from StandardError
retry # This executes the begin section again
else
# This is executed only if no exceptions were raised
ensure
# This is always executed, exception or not
end
Сленг
try { % code that might throw an exception } catch SomeError: { % code that handles this exception } catch SomeOtherError: { % code that handles this exception } finally % optional block { % This code will always get executed }
Новые исключения могут быть созданы с помощью new_exception
функции, например,
new_exception ("MyIOError", IOError, "My I/O Error");
создаст исключение, называемое MyIOError
подклассом IOError
. Исключения могут быть сгенерированы с помощью оператора throw, который может генерировать произвольные объекты S-Lang .
Болтовня
[ "code that might throw an exception" ]
on: ExceptionClass
do: [:ex | "code that handles exception" ].
Общий механизм обеспечивается сообщением . Исключения - это просто обычные объекты, которые являются подклассом , вы создаете один, создавая экземпляр и отправляя ему сообщение, например . Механизм обработки ( ) снова представляет собой обычное сообщение, реализованное с помощью . Вызванное исключение передается в качестве параметра в закрытие блока обработки и может быть запрошено, а также может быть отправлено ему, чтобы разрешить поток выполнения.
on:do:
Error
#signal
MyException new signal
#on:do:
BlockClosure
#resume
Быстрый
Обработка исключений поддерживается начиная со Swift 2.
enum MyException : ErrorType {
case Foo(String, Int)
}
func someFunc() throws {
throw MyException.Foo("not enough food", 2)
}
do {
try someFunc()
print("Not reached")
} catch MyException.Foo(let s, let i) {
print("MyException: \(s), \(i)")
} catch {
print("Unexpected exception : \(error)")
}
Tcl
if { [ catch {
foo
} err ] } {
puts "Error: $err"
}
Начиная с Tcl 8.6, есть также команда try:
try {
someCommandWithExceptions
} on ok {res opt} {
# handle normal case.
} trap ListPattern1 {err opt} {
# handle exceptions with an errorcode matching ListPattern1
} trap ListPattern2 {err opt} {
# ...
} on error {err opt} {
# handle everything else.
} finally {
# run whatever commands must run after the try-block.
}
VBScript
With New Try: On Error Resume Next
'do Something (only one statement recommended)
.Catch: On Error GoTo 0: Select Case .Number
Case 0 'this line is required when using 'Case Else' clause because of the lack of "Is" keyword in VBScript Case statement
'no exception
Case SOME_ERRORNUMBER
'exception handling
Case Else
'unknown exception
End Select: End With
' *** Try Class ***
Class Try
Private mstrDescription
Private mlngHelpContext
Private mstrHelpFile
Private mlngNumber
Private mstrSource
Public Sub Catch()
mstrDescription = Err.Description
mlngHelpContext = Err.HelpContext
mstrHelpFile = Err.HelpFile
mlngNumber = Err.Number
mstrSource = Err.Source
End Sub
Public Property Get Source()
Source = mstrSource
End Property
Public Property Get Number()
Number = mlngNumber
End Property
Public Property Get HelpFile()
HelpFile = mstrHelpFile
End Property
Public Property Get HelpContext()
HelpContext = mlngHelpContext
End Property
Public Property Get Description()
Description = mstrDescription
End Property
End Class
Visual Basic 6
Синтаксис обработки исключений очень похож на базовый. Обработка ошибок локальна для каждой процедуры.
On Error GoTo HandlerLabel 'When error has occurred jumps to HandlerLabel, which is defined anywhere within Function or Sub
'or
On Error GoTo 0 'switch off error handling. Error causes fatal runtime error and stops application
'or
On Error Resume Next 'Object Err is set, but execution continues on next command. You can still use Err object to check error state.
'...
Err.Raise 6 ' Generate an "Overflow" error using build-in object Err. If there is no error handler, calling procedure can catch exception by same syntax
'...
FinallyLabel: 'just common label within procedure (non official emulation of Finally section from other languages)
'cleanup code, always executed
Exit Sub 'exits procedure
'because we are after Exit Sub statement, next code is hidden for non-error execution
HandlerLabel: 'defines a common label, here used for exception handling.
If Err.Number = 6 Then 'Select Case statement is typically better solution
Resume FinallyLabel 'continue execution on specific label. Typically something with meaning of "Finally" in other languages
'or
Resume Next 'continue execution on statement next to "Err.Raise 6"
'or
Resume 'continue execution on (repeat) statement "Err.Raise 6"
End If
MsgBox Err.Number & " " & Err.Source & " " & Erl & " " & Err.Description & " " & Err.LastDllError 'show message box with important error properties
'Erl is VB6 build-in line number global variable (if used). Typically is used some kind of IDE Add-In, which labels every code line with number before compilation
Resume FinallyLabel
Пример конкретной (неофициальной) реализации обработки исключений, использующей объект класса «Try».
With New Try: On Error Resume Next 'Create new object of class "Try" and use it. Then set this object as default. Can be "Dim T As New Try: ... ... T.Catch
'do Something (only one statement recommended)
.Catch: On Error GoTo 0: Select Case .Number 'Call Try.Catch() procedure. Then switch off error handling. Then use "switch-like" statement on result of Try.Number property (value of property Err.Number of build-in Err object)
Case SOME_ERRORNUMBER
'exception handling
Case Is <> 0 'When Err.Number is zero, no error has occurred
'unknown exception
End Select: End With
' *** Try Class ***
Private mstrDescription As String
Private mlngHelpContext As Long
Private mstrHelpFile As String
Private mlngLastDllError As Long
Private mlngNumber As Long
Private mstrSource As String
Public Sub Catch()
mstrDescription = Err.Description
mlngHelpContext = Err.HelpContext
mstrHelpFile = Err.HelpFile
mlngLastDllError = Err.LastDllError
mlngNumber = Err.Number
mstrSource = Err.Source
End Sub
Public Property Get Source() As String
Source = mstrSource
End Property
Public Property Get Number() As Long
Number = mlngNumber
End Property
Public Property Get LastDllError() As Long
LastDllError = mlngLastDllError
End Property
Public Property Get HelpFile() As String
HelpFile = mstrHelpFile
End Property
Public Property Get HelpContext() As Long
HelpContext = mlngHelpContext
End Property
Public Property Get Description() As String
Description = mstrDescription
End Property
Visual Basic .NET
В Try
блоке должно быть хотя бы одно предложение Catch
или Finally
предложение и не более одного Finally
предложения.
Try
' code to be executed here
Catch ex As Exception When condition
' Handle Exception when a specific condition is true. The exception object is stored in "ex".
Catch ex As ExceptionType
' Handle Exception of a specified type (i.e. DivideByZeroException, OverflowException, etc.)
Catch ex As Exception
' Handle Exception (catch all exceptions of a type not previously specified)
Catch
' Handles anything that might be thrown, including non-CLR exceptions.
Finally
' Always run when leaving the try block (including catch clauses), regardless of whether any exceptions were thrown or whether they were handled.
' Often used to clean up and close resources such a file handles.
' May not be run when Environment.FailFast() is called and in other system-wide exceptional conditions (e.g. power loss), or when the process crashes due to an exception in another thread.
End Try
Визуальный пролог
http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Try-catch-finally
try
% Block to protect
catch TraceId do
% Code to execute in the event of an exception; TraceId gives access to the exception information
finally
% Code will be executed regardles however the other parts behave
end try
X ++
public static void Main(Args _args)
{
try
{
// Code that could throw an exception.
}
catch (Exception::Error) // Or any other exception type.
{
// Process the error.
}
catch
{
// Process any other exception type not handled previously.
}
// Code here will execute as long as any exception is caught.
}
использованная литература
Смотрите также
- Обработка исключений для семантики обработки исключений
- Синтаксис для определения синтаксиса в информатике