Jump to content

Синтаксис обработки исключений

Синтаксис обработки исключений — это набор ключевых слов и/или структур, предоставляемых языком программирования для обеспечения обработки исключений , который отделяет обработку ошибок, возникающих во время работы программы, от ее обычных процессов. Синтаксис обработки исключений варьируется в зависимости от языка программирования каждого языка , отчасти для того, чтобы скрыть семантические различия, но в основном для того, чтобы вписаться в общую синтаксическую структуру . Некоторые языки не называют соответствующую концепцию « обработкой исключений »; другие могут не иметь для этого прямых возможностей, но все же могут предоставить средства для его реализации.

Чаще всего для обработки ошибок используется 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 . Системы Digital Equipment Corporation RT11 имели векторы-ловушки для программных ошибок, прерываний ввода-вывода и т. д. В 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

Структура goto/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 является использование 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;
}

А 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.
    }
}
#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. [1] Внешние скобки для метода не являются обязательными.

Язык разметки 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 [2]

Синтаксис тегов

[ редактировать ]
<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 [3]

Специальный синтаксис Railo-Lucee

[ редактировать ]

В дополнение к стандартному синтаксису, указанному выше, диалекты CFML Railo и Lucee позволяют retry заявление. [4]

Этот оператор возвращает обработку к началу предыдущего 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>
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;
}

В Д, а finally Предложение или метод инициализации получения ресурсов можно использовать для очистки ресурсов в исключительных ситуациях.

Объявления исключений
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);
Обработка и распространение исключений [5]
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;
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

В дополнение к основанному на 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 нет специального синтаксиса для исключений. Вместо этого 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)

по аналогии с этим С++

#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 типа может быть достаточно, и он является экземпляром Haskell 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 not be run when System.exit() is called and in other system-wide exceptional conditions (e.g. power loss).
}

Дизайн 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 использует сборку мусора по принципу «пометить и очистить», никогда не происходит утечки памяти из-за операторов 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
}

Общий Лисп

[ редактировать ]
(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."))

Луа использует 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) {
  # ...
}
Игнорирование исключений – попробуйте без catch
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
  }
}
Объявления исключений
NSException *exception = [NSException exceptionWithName:@"myException"
                           reason:@"yourReason"  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.
    ...
}
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 для обработки исключений использует die чтобы вызвать исключение при обертывании внутри eval { ... }; блокировать. После eval, специальная переменная $@ содержит значение, переданное из die.

В 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 $@'
    }
}

The __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);
    }
};

Формы, показанные выше, иногда могут давать сбой, если глобальная переменная $@ изменяется между моментом выдачи исключения и моментом его проверки в if ($@) заявление. Это может произойти в многопоточных средах или даже в однопоточных средах, когда другой код (обычно вызывается при уничтожении некоторого объекта) сбрасывает глобальную переменную перед проверочным кодом. Следующий пример показывает способ избежать этой проблемы (см. [1] [ мертвая ссылка ] или [2] ; ср . [3] ). Но за счет невозможности использовать возвращаемые значения:

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::Tiny и Nice::Try все они позволяют использовать синтаксис try/catch/finally вместо шаблонного для правильной обработки исключений.
  • Exception::Class является базовым классом и создателем классов для производных классов исключений. Он обеспечивает полную структурированную трассировку стека в $@->trace и $@->trace->as_string.
  • Fatal перегружает ранее определенные функции, которые возвращают true/false, например, open, close, read, writeи т. д. Это позволяет использовать встроенные и другие функции так, как если бы они создавали исключения.
// 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 версии 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

Версия 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
    }
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
 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:. [6] Исключения — это обычные объекты, которые являются подклассами 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)")
}
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.
}
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

[7]

Визуал Бейсик 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

[7]

Визуальный Бейсик .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

Визуальный Пролог

[ редактировать ]
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

[8]

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.
}
  1. ^ Часто задаваемые вопросы Бьярна Страуструпа
  2. ^ «Обработка исключений» . Архивировано из оригинала 2 января 2014 г. Проверено 1 января 2014 г.
  3. ^ «Теги обработки исключений» . Архивировано из оригинала 2 января 2014 г. Проверено 1 января 2014 г.
  4. ^ https://issues.jboss.org/browse/RAILO-2176 # Билет отслеживания проблем сообщества JBoss для добавления retry
  5. ^ Borland, Delphi Версия 7.0, Интернет-справка
  6. ^ «Фарон на примере» . Архивировано из оригинала 21 октября 2009 г. Проверено 20 марта 2010 г.
  7. ^ Jump up to: а б «Попробуй-поймай для VB» . Архивировано из оригинала 16 апреля 2016 г. Проверено 17 марта 2012 г.
  8. ^ http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Try-catch-finally

См. также

[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 63f3e269abe13a1d4b5e8a4ca90c8796__1719307740
URL1:https://arc.ask3.ru/arc/aa/63/96/63f3e269abe13a1d4b5e8a4ca90c8796.html
Заголовок, (Title) документа по адресу, URL1:
Exception handling syntax - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)