Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

Чаще всего для обработки ошибок используется try...[catch...][finally...]блок, а ошибки создаются с помощью throwоператора, но существуют значительные различия в именах и синтаксисе.

Каталог синтаксисов обработки исключений [ править ]

Ада [ править ]

Объявления исключений
Some_Error  :  исключение ;
Вызов исключений
поднять  Some_Error ;вызвать  Some_Error  с  " Недостаточно памяти" ;  - специальное диагностическое сообщение
Обработка и распространение исключений
с  Ada.Exceptions ,  Ada . Text_IO ;процедура  Foo  - это  Some_Error  :  exception ; begin  Do_Something_Interesting ; исключение  - Запуск обработчиков исключений,  когда  Constraint_Error  =>  ...  - Обрабатывать ошибку ограничения,  когда  Storage_Error  =>  - Распространять Storage_Error как другое исключение с полезным сообщением,  поднимать  Some_Error  с  "Out of memory" ;  when  Error  :  others  =>  - обрабатывать все остальные  Ada . Текст_IO . Поместите ( "Исключение:");  Ада . Текст_IO . Put_Line ( Ada . Исключения . Exception_Name ( Ошибка ));  Ада . Текст_IO . Put_Line ( Ada . Исключения . Exception_Message ( Ошибка )); конец  Foo ;

Язык ассемблера [ править ]

Большинство языков ассемблера будут иметь макро-инструкцию или адрес прерывания, доступный для конкретной системы, чтобы перехватывать такие события, как недопустимые коды операций, проверка программы, ошибки данных, переполнение, деление на ноль и другие подобные. В мэйнфреймах IBM и Univac был макрос STXIT . В системах RT11 компании Digital Equipment Corporation были векторы ловушек для программных ошибок, прерываний ввода-вывода и т. Д. DOS имеет определенные адреса прерывания. В Microsoft Windows есть специальные вызовы модулей для обнаружения ошибок программы.

Баш [ править ]

#! / USR / бен / окр Баш #set -e обеспечивает другой механизм ошибки
print_error () { эхо  "произошла ошибка" } ловушки print_error выхода  #list сигналы ловушки TempFile = ` Mktemp ` ловушки  "ет $ TempFile "  выход
. /other.sh ||  эхо предупреждение: другие неудачные эхо упс ) эхо никогда не печаталось

Можно установить ловушку для множественных ошибок, отвечая на любой сигнал синтаксисом типа:

trap 'echo Error at line ${LINENO}' ERR

ОСНОВНОЙ [ править ]

On Error Гото / GoSub структура используется в BASIC и довольно сильно отличается от современной обработки исключений; в BASIC есть только один глобальный обработчик, тогда как в современной обработке исключений обработчики исключений складываются.

ON ERROR GOTO обработчиком ОТКРЫТЫЙ "Somefile.txt" ДЛЯ ВВОДА AS # 1 CLOSE # 1 PRINT "Файл открыт успешно" END         обработчик: PRINT "Файл не существует" END 'RESUME может использоваться вместо этого, которое возвращает управление в исходное положение.  

C [ править ]

C не обеспечивает прямой поддержки обработки исключений: программист обязан в первую очередь предотвращать ошибки и проверять возвращаемые значения функций.

В любом случае возможный способ реализовать обработку исключений в стандартном C - использовать функции setjmp / longjmp :

#include  <setjmp.h>#include  <stdio.h>#include  <stdlib.h>enum  {  SOME_EXCEPTION  =  1  }  исключение ; состояние jmp_buf  ;int  main ( void ) {  if  ( ! setjmp ( state ))  // попробуйте  {  if  ( / * что-то произошло * / )  {  exception  =  SOME_EXCEPTION ;  longjmp ( состояние ,  0 );  // бросок SOME_EXCEPTION  }  }  еще  переключатель ( исключение )  {  случай  SOME_EXCEPTION :  // поймать SOME_EXCEPTION  путы ( "SOME_EXCEPTION пойманы" );  перемена;  default :  // catch ...  put ( "Странное исключение" );  }  return  EXIT_SUCCESS ; }

Специально для Microsoft [ править ]

Существуют два типа:

  • Структурированная обработка исключений (SEH)
  • Векторная обработка исключений (VEH, представленная в Windows XP )

Пример SEH на языке программирования C:

int  filterExpression  ( EXCEPTION_POINTERS *  ep )  {  ep -> ContextRecord -> Eip  + =  8 ;  // инструкция деления может быть закодирована от 2 до 8 байтов  return  EXCEPTION_CONTINUE_EXECUTION ; } int  main ( void )  {  статический  int  ноль ;  __ попробуйте  {  ноль  =  1 / ноль ;  __asm  {  ноп  ноп  ноп  ноп  ноп  ноп  ноп }  printf  ( "Прошлое исключение. \ n " );  }  __except  ( filterExpression  ( GetExceptionInformation ()))  {  printf  ( "Обработчик вызван. \ n " );  }  return  0 ; }

C # [ править ]

В tryблоке должно быть хотя бы одно предложение catchили finallyи не более одного finallyпредложения.

public  static  void  Main () {  try  {  // Код, который может вызвать исключение.  }  catch  ( HttpException  ex )  {  // Обрабатывает HttpException. Объект исключения хранится в ex.  }  catch  ( Exception )  {  // Обрабатывает любое исключение CLR, которое не является HttpException.  // Поскольку исключению не был присвоен идентификатор, на него нельзя ссылаться.  }  catch  {  // Обрабатывает все, что может быть сгенерировано, включая исключения, не связанные с CLR.  }  finally  { // Всегда запускать при выходе из блока try (включая предложения catch), независимо от того, были ли выброшены какие-либо исключения или они были обработаны.  // Часто используется для очистки и закрытия ресурсов, которые обрабатывает такой файл.  // Не может быть запущен при вызове Environment.FailFast () и в других общесистемных исключительных условиях (например, потеря мощности) или когда процесс завершается сбоем из-за исключения в другом потоке.  } }

C ++ [ править ]

#include  <исключение>int  main ()  {  try  {  // сделать что-то (может вызвать исключение)  }  catch  ( const  std :: exception &  e )  {  // обработать исключение e  }  catch  (...)  {  // перехватить все исключения, еще не пойманный блоком catch перед  // может использоваться для перехвата исключения неизвестного или нерелевантного типа  } }

В C ++ получение ресурсов - это метод инициализации , который может использоваться для очистки ресурсов в исключительных ситуациях. C ++ намеренно не поддерживает finally. [1] Внешние скобки для метода необязательны.

Язык разметки ColdFusion (CFML) [ править ]

Синтаксис скрипта [ править ]

< cfscript > try  { // throw CF9 + throw ( type = "TypeOfException" ,  message = "Oops" ,  detail = "xyz" ); // альтернативный синтаксис throw: throw  "Oops" ;  // это эквивалент значению "message" в приведенном выше примере }  catch  ( any  e )  { writeOutput ( "Error:"  &  e . message ); перебросить ;    // CF9 + writeOutput ( «Я бегу, даже если нет ошибок» ); } < / cfscript>

Документация Adobe ColdFusion [2]

Синтаксис тега [ править ]

<cftry>  код, который может вызвать исключение  <cfcatch  ... >  <cftry>  Первый уровень кода обработки исключений  <cfcatch  ... >  Второй уровень кода обработки исключений  </cfcatch>  < cffinally >  окончательный код  </ cffinally >  </cftry>  </cfcatch>  </cftry>

Документация Adobe ColdFusion [3]

Особый синтаксис Рейло-Люси [ править ]

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

Этот оператор возвращает обработку к началу предыдущего tryблока.

Пример CFScript:

try  { // код, который может привести к исключению}  поймать  ( любой  е ) { повторить ; }

Пример синтаксиса тега:

<cftry><! --- код, который может привести к исключению ---><cfcatch> < cfretry > </cfcatch> </cftry>

D [ править ]

импорт  std . stdio ;  // для writefln () int  main ()  {  try  {  // сделать что-то, что может  вызвать исключение }  catch  ( FooException  e )  {  // обработать исключения типа FooException  }  catch  ( Object  o )  {  // обработать любые другие исключения  writefln ( "Необработанное исключение:" ,  o );  возврат  1 ;  }  return  0 ; }

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

Delphi [ править ]

Объявления исключений
type  ECustom  =  class ( Exception )  // Исключения являются потомками класса Exception.  частный  FCustomData :  SomeType ;  // Исключения могут иметь собственные расширения.  открытый  конструктор  CreateCustom ( Data :  SomeType ) ;  // Требуется  свойство  реализации CustomData :  SomeType  read  FCustomData ;  конец ;
Вызов исключений
поднять  исключение . Создать ( 'Сообщение' ) ;поднять  исключение . CreateFmt ( 'Сообщение со значениями:% d,% d' , [ значение1 ,  значение2 ]) ;  // См. Параметры в SysUtils.Format ().поднять  ECustom . CreateCustom ( X ) ;
Обработка и распространение исключений [5]
try  // Ибо наконец.  try  // For except.  ...  // Код, который может вызвать исключение.  за исключением того,  на  C : ECustom  делать  начинаются  ...  // Handle ECustom.  ...  если  Предикат ( C . CustomData ) ,  то  ...  конец ;  на  S : ESomeOtherException  действительно  начинается  // Распространяется как другое исключение.  поднять  EYetAnotherException . Создать ( S . Message ) ;  конец;  на  E : Exception  do  begin  ...  // Обработка других исключений.  поднять ;  // Распространение.  конец ;  конец ;  finally  // Код для выполнения независимо от того, возникло ли исключение (например, код очистки). конец ;

Эрланг [ править ]

попробуйте  % some опасный код catch  throw : { someError ,  X }  ->  ok ;  % обрабатывает  ошибку исключения : X  ->  ok ;  % Обрабатывать еще одно исключение  _: _  ->  ОК  % ручка все исключения после  % чистой до конца

F # [ править ]

В дополнение к основанной на OCaml try...with, F # также имеет отдельную try...finallyконструкцию, которая имеет то же поведение, что и блок try с finallyпредложением на других языках .NET.

Для сравнения это перевод приведенного выше примера C # .

попробуйте  try  ()  (* Код, который может вызвать исключение. *)  с  |  :?  Система . Нетто . WebException  as  ex  ->  ()  (* Обрабатывает WebException. Объект исключения хранится в "ex" . *)  |  :?  exn  ->  ()  (* Обрабатывает любое исключение CLR. Поскольку исключению не был присвоен идентификатор, на него нельзя ссылаться. *)  |  _  ->  ()  (* Обрабатывает все, что может быть сгенерировано, включая исключения, не относящиеся к среде CLR. *) Finally  ()  (* Всегда запускать при выходе из блока try, независимо от того, были ли выброшены какие-либо исключения или были ли они обработаны.  Часто используется для очистки и закрытия ресурсов, с которыми работает такой файл.  Не может быть запущен при вызове Environment.FailFast () и в других общесистемных исключительных условиях (например, потеря мощности) или когда процесс завершается сбоем из-за исключения в другом потоке.  *)

Для сравнения это перевод примера OCaml ниже .

Исключение  MyException  из  строки  *  INT  (* исключения могут нести значение *) пусть  _  =  попробовать  рейз  ( MyException  ( "не хватает еды" ,  2 ));  printfn  "Не достигнуто"  с помощью  |  MyException  ( s ,  i )  ->  printf  "MyException:% s,% d \ n "  s  i  |  e  ->  (* поймать все исключения *)  eprintf  "Неожиданное исключение:% O"  e ;  eprintf "% O"  e . Трассировки стека

Haskell [ править ]

В Haskell нет специального синтаксиса для исключений. Вместо этого try/ catch/ finally/ etc. интерфейс предоставляется функциями.

import  Prelude  скрытие ( 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>используя  пространство имен  std ; int  main () {  try  { throw  ( int ) 42 ;}  catch ( double  e )  { cout  <<  "(0,"  <<  e  <<  ")"  <<  endl ;}  catch ( int  e )  { cout  <<  "(1,"  <<  e  <<  ")"  <<  endl ;} }

Другой пример

делать  {  - Заявления , в которых ошибки могут быть отброшены }  ` поймать `  \ ех  ->  делать  {  - Заявления , которые выполняются в случае исключения, с «бывшим» , связанными с исключением }

В чисто функциональном коде, если только одно условие ошибки существует, Maybeтип может быть достаточно, и является экземпляром Хаскеля Monad класса по умолчанию. Более сложное распространение ошибок может быть достигнуто с помощью монад Errorили ErrorT, для которых поддерживается аналогичная функциональность (использование ).`catch`

Java [ править ]

В tryблоке должно быть хотя бы одно предложение catchили finallyи не более одного finallyпредложения.

try  {  // Нормальный путь выполнения.  throw  new  EmptyStackException (); }  catch  ( ExampleException  ee )  {  // Обработка исключения ExampleException. }  finally  {  // Всегда запускать при выходе из блока try (включая предложения finally), независимо от того, были ли выданы какие-либо исключения или они были обработаны.  // Часто используется для очистки и закрытия ресурсов, которые обрабатывает такой файл.  // Не может быть запущен при вызове System.exit () и в других общесистемных исключительных условиях (например, при потере питания). }

JavaScript [ править ]

Дизайн JavaScript очень редко допускает громкие / серьезные ошибки. Мягкие / тихие ошибки гораздо более распространены. Серьезные ошибки распространяются на ближайший tryоператор, за которым должно следовать либо одно catchпредложение, либо одно finallyпредложение, либо оба предложения.

try  {  // Операторы, в которых могут возникать исключения  throw  new  Error ( "error" ); }  catch ( error )  {  // Операторы, которые выполняются в случае исключения }  finally  {  // Операторы, которые выполняются позже в любом случае }

Если нет никакого tryзаявления, тогда веб-страница не вылетает. Вместо этого в консоль регистрируется ошибка, и стек очищается. Однако у JavaScript есть интересная особенность асинхронных точек входа, вызываемых извне. В то время как в большинстве других языков всегда есть какая-то часть кода, работающая постоянно, JavaScript не обязательно должен выполняться линейно от начала до конца. Например, прослушиватели событий, обещания и таймеры могут быть вызваны браузером в более поздний момент времени и запущены в изолированном, но общем контексте с остальной частью кода. Обратите внимание, как приведенный ниже код будет выдавать новую ошибку каждые 4 секунды в течение неопределенного периода времени или до тех пор, пока браузер / вкладка / компьютер не будут закрыты.

setInterval ( function ()  {  throw  new  Error ( "Пример ошибки, выданной через 4-секундный интервал." ); },  4000 );

Еще одна интересная особенность - полиморфизм: JavaScript может выдавать примитивные значения как ошибки.

попробуйте  {  бросить  12345 ;  // примитивное число }  catch ( error )  {  console . журнал ( ошибка );  // выводит в консоль 12345 как примитивное число }

Обратите внимание, что это catchпредложение является универсальным, в нем учитываются все типы ошибок. Нет синтаксической возможности назначать разные обработчики для разных типов ошибок, кроме экспериментальных и удаленных в настоящее время расширений Gecko много лет назад. Вместо этого можно либо распространить ошибку, используя throwоператор внутри catchоператора, либо использовать несколько условных случаев. Давайте сравним пример на Java и его приблизительные эквиваленты на JavaScript.

// Пример на Java try  {  Integer  i  =  null ;  я . intValue ();  // генерирует исключение NullPointerException }  catch ( ошибка NullPointerException  ) { // переменная может иметь значение null } catch ( ошибка ArithmeticException ) { // Решаем проблемы с числами }      
// Приближение №1 в JavaScript try  {  // Заявления, в которых могут возникать исключения  var  example  =  null ;  пример . toString (); }  catch ( error )  {  if  ( error . type  ===  "TypeError" )  {  // Переменная может иметь значение null  }  else  if  ( error . type  ===  "RangeError" )  {  //  Решение проблем с числами } }
// Приближение №2 в JavaScript try  {  try  {  // Заявления, в которых могут возникать исключения  var  example  =  null ;  пример . toString ();  }  catch ( error )  {  if  ( error . type  ! ==  "TypeError" )  выбросить  ошибку ;  // Переменная может иметь значение null  } }  catch ( error )  {  if  ( error . Type  ! ==  "RangeError")  выбросить  ошибку ;  // Решаем проблемы с числами }

Другой аспект исключений - это обещания, которые обрабатывают исключение асинхронно. Асинхронная обработка исключения имеет то преимущество, что ошибки внутри обработчика ошибок не распространяются дальше вовне.

new  Promise ( function ()  { throw  new  Error ( "Пример ошибки!" ); }). catch ( функция ( ошибка )  { консоль . журнал ( "Поймано" ,  ошибка ); });

Также обратите внимание, как обработчики событий могут быть связаны с обещаниями.

addEventListener ( "unhandledrejection" ,  функция ( событие )  {  консоль . журнал ( событие . причина );  событие . preventDefault ();  // предотвращения регистрации ошибок с помощью console.error на консоль - поведение по умолчанию });new  Promise ( function ()  {  throw  new  Error ( "Пример ошибки!" ); });

Наконец, обратите внимание, что, поскольку JavaScript использует сборку мусора mark-and-sweep, никогда не происходит утечки памяти из-за операторов throw, потому что браузер автоматически очищает мертвые объекты - даже с циклическими ссылками.

try  {  // Операторы, в которых могут возникать исключения  const  obj  =  {};  OBJ . selfPropExample  =  obj ;  // круговая ссылка  throw  obj ; }  catch ( error )  {  // Операторы, которые выполняются в случае исключения }

Лисп [ править ]

Common Lisp [ править ]

( игнорировать ошибки  ( /  1  0 ))( обработчик-case  ( progn  ( print  "введите выражение" )  ( eval  ( чтение )))  ( error  ( e )  ( print  e )))( размотка-защита  ( progn  ( print  "введите выражение" )  ( eval  ( чтение )))  ( print  "Эта печать всегда будет выполняться, как и finally." ))

Lua [ править ]

Lua использует pcallи xpcallфункции, с xpcallпринимая функцию , чтобы действовать в качестве catchблока.

Предопределенная функция
function  foo ( x )  if  x,  затем  вернуть  x  else  error  "Not a true value"  end end попытка функции ( аргумент )  успех ,  значение  =  pcall ( foo ,  arg ) если  не  удалось,  то  print ( "Error:"  ..  tostring ( value ))  else  print ( "Returned:"  ..  tostring ( value ))  end endпопытка ( "привет" )  - Возвращено: приветпопытка ( nil )  - Ошибка: stdin: 5: неверное значениепопытка ({})  - Возвращено: таблица: 00809308 если  foo ( 42 ),  то  выведите  "Success"  end  - Success
Анонимная функция
если  pcall (  function ()  - Сделайте что-нибудь, что может  вызвать ошибку. end ),  затем  выведите  «Нет ошибок»  - Выполняется, если защищенный вызов был успешным. else  print  «Обнаружена ошибка»  - Выполняется, если защищенный вызов не удался. конецprint  "Готово"  - всегда будет выполняться

Оболочка нового поколения [ править ]

Определение настраиваемого типа исключения
тип MyError ( Ошибка )
Вызов исключений
throw  MyError ( "это случилось" )
Обработка и распространение исключений
попробуйте  {  # something }  catch ( e : MyError )  {  guard  e . val  =  7  # ... }  catch ( e : MyError )  {  # ... }  catch ( e : Error )  {  # ... }
Игнорирование исключений - попробуйте без уловки
попробуйте  1 / 0  # принимает значение NULL
Игнорирование исключений - оператор "tor"

"tor" - это оператор try-or. В случае какого-либо исключения при оценке аргумента слева оценивается аргумент справа.

1 / 0  тор  20  # принимает значение 20
«блок» - возможность использовать исключения для возврата значения
my_result  =  block  my_block  {  # "block" перехватывает исключение,  генерируемое возвратом ниже # выполнить расчет,  если  вычисление_finished ()  {  my_block . return ( 42 )  # выдает исключение  } }

Objective-C [ править ]

Объявления исключений
NSException  * exception  =  [ NSException  exceptionWithName : @ "myException"  причина : @ "что угодно"  userInfo : nil ];
Вызов исключений
@throw  исключение ;
Обработка и распространение исключений
@try  {  ... } @catch  ( SomeException  * se )  {  // Обрабатываем определенный тип исключения.  ... } @catch  ( NSException  * ne )  {  // Обрабатываем общие исключения.  ... // Распространение исключения так, чтобы оно обрабатывалось на более высоком уровне.  @throw ; } @catch  ( id  ue )  {  // Лови все брошенные предметы.  ... } @finally  {  //  Выполняем очистку независимо от того, произошло исключение или нет. ... }

OCaml [ править ]

Исключение  MyException  из  строки  *  INT  (* исключения могут нести значение *) пусть  _  =  попробовать  рейз  ( MyException  ( "не хватает еды" ,  2 ));  print_endline  "Не достигнуто"  с  |  MyException  ( s ,  i )  ->  Printf . printf  "MyException:% s,% d \ n "  s  i  |  e  ->  (* поймать все исключения *)  Printf . eprintf «Неожиданное исключение:% s»  ( Printexc . To_string  e );  (* Если используется Ocaml> = 3.11, можно также распечатать обратную трассировку: *)  Printexc . print_backtrace  stderr ;  (* Необходимо заранее включить запись  обратной трассировки с помощью Printexc.record_backtrace true  или путем установки переменной среды OCAMLRUNPARAM = "b1" *)

Perl 5 [ править ]

Механизм Perl для обработки исключений использует dieдля создания исключения при заключении в блок. После , специальная переменная содержит значение, переданное из . Однако проблемы с областью видимости могут сделать это правильно довольно некрасивым:eval { ... };eval$@die

my  ( $ error ,  $ failed ); {  местный  $ @ ;  $ failed  =  not  eval  {  # Код, который может вызвать исключение (с помощью 'die')  open ( FILE ,  $ file )  ||  die  "Не удалось открыть файл: $!" ;  в то время как  ( <FILE> )  {  process_line ( $ _ );  }  закрыть ( ФАЙЛ )  ||  die  "Не удалось закрыть $ file: $!" ;  возврат  1 ;  }; $ error  =  $ @ ; }if  ( $ failed )  {  предупреждение  "получена ошибка: $ error" ; }

Perl 5.005 добавил возможность бросать объекты, а также строки. Это позволяет лучше анализировать и обрабатывать типы исключений.

eval  {  open ( FILE ,  $ file )  ||  die  MyException :: File -> новый ( $! );  в то время как  ( <FILE> )  {  process_line ( $ _ );  }  закрыть ( ФАЙЛ )  ||  die  MyException :: File -> новый ( $! ); }; if  ( $ @ )  {  # Объект исключения находится в $ @  if  ( $ @ -> isa ('MyException :: File' ))  {  # Обработка исключения файла  }  else  {  # Общая обработка исключений  # или повторная генерация с помощью 'die $ @'  } }

__DIE__Псевдо-сигнал может задерживаться для обработки вызовов в die. Это не подходит для обработки исключений, поскольку является глобальным. Однако его можно использовать для преобразования исключений на основе строк из сторонних пакетов в объекты.

локальный  $ SIG { __DIE__ }  =  sub  {  мой  $ err  =  shift ;  если  ( $ err -> isa ( 'MyException' ))  {  die  $ err ;  # повторно выбросить  }  else  {  # В противном случае создайте MyException с $ err в виде строки  die  MyException :: Default -> new ( $ err );  } };

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

eval  {  # Код, который может вызвать исключение (с использованием 'die'), но НЕ использует оператор return;  1 ; }  или  сделайте  {  # Обработать исключение здесь. Строка исключения находится в $ @ };

Несколько модулей в 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 [ править ]

// Обработка исключений доступна только в PHP версии 5 и выше. try  {  // Код, который может вызвать исключение  throw  new  Exception ( 'Invalid URL.' ); }  catch  ( FirstExceptionClass  $ exception )  {  // Код, обрабатывающий это исключение }  catch  ( SecondExceptionClass  $ exception )  {  // Код, обрабатывающий другое исключение }  finally  {  // Выполняем очистку независимо от того, произошло ли исключение или нет. }

PowerBuilder [ править ]

Обработка исключений доступна в PowerBuilder версии 8.0 и выше.

ПЫТАТЬСЯ // Нормальный путь выполненияCATCH (ExampleException ee) // работаем с ExampleExceptionНАКОНЕЦ-ТО // Этот необязательный раздел выполняется после завершения любого из блоков try или catch вышеКОНЕЦ ПОПЫТКИ

PowerShell [ править ]

Версия 1.0 [ править ]

trap  [Exception] {  # операторов, которые выполняются в случае исключения } # операторов, в которых могут возникать исключения

Версия 2.0 [ править ]

Попробуйте  {  Import-Module  ActiveDirectory  } Catch  [Exception1]  {  #  операторов, которые выполняются в случае исключения, соответствующего исключению } Catch  [Exception2], [Exception3etc]  {  # операторов, которые выполняются в случае исключения, соответствующего любому из исключения  } Catch  {  # Операторы, которые выполняются в случае исключения, не обрабатываются более конкретно  }

Python [ править ]

f  =  Нет попытки :  f  =  open ( "aFileName" ,  "w" )  f . write ( could_make_error ()) except  IOError :  print ( «Невозможно открыть файл» ) except :  # перехватить все исключения  print ( «Неожиданная ошибка» ) else :  # выполняется, если не возникло никаких исключений  print ( «Запись файла завершена успешно» ) наконец :  # действия по очистке, всегда выполняются,  если ж :  ж . закрыть ()

R [ править ]

tryCatch ({  stop ( "Здесь сообщается об ошибке" )  # S3-класс по умолчанию - simpleError подкласс error  cat ( "Эта и следующие строки не выполняются, потому что ошибка перехвачена до \ n" )  stop (  structure ( simpleError ( "сообщение mySpecialError" ), class = c ( "specialError" , "error" , "condition" ))  ) } , specialError = function ( e ) {  cat ("обнаруживает ошибки класса specialError \ n" ) } , error = function ( e ) {  cat ( "обнаруживает ошибку по умолчанию \ n" ) } , наконец = {  cat ( "выполните некоторую очистку (например, setwd) \ n" )  } )

Ребол [ править ]

REBOL [  Название:  «Примеры обработки исключений и ошибок» ]; ПОПРОБУЙТЕ блок; фиксация ошибки! и преобразование в объект! если  ошибка?  исключение:  попытка  [ 1  /  0 ] [ зонд  разоружите  исключение ]; ATTEMPT приводит к значению блока или к значению none при попытке печати  ошибки [ делить 1 0 ]   ; Пользовательские исключения могут иметь любой тип данных! пример:  func  [ "Функция, генерирующая исключение" ] [  throw  "Я строка! исключение" ] catch  [ пример ]; Исключения, созданные пользователем, также могут быть названы ; и функции могут включать дополнительные сложные  атрибуты времени выполнения : func  [ "Функция для выдачи именованного исключения ошибки"  [ catch ] ] [  throw / name  make  error!  «Я - ошибка! Исключение»  'прозвище ] catch / name  [ сложное ]  ' прозвище

Rexx [ править ]

 сигнал об остановке ;   сделать = 1    говорят  do 100000 / * задержка * /   конец конец остановка : сказать "Программа была остановлена ​​пользователем"  выход

Руби [ править ]

begin  # Сделайте что-нибудь  изящное , поднимите  SomeError ,  "Это сообщение об ошибке!"  # Ой-ой! rescue  SomeError  # Это выполняется, когда возникает исключение SomeError  # rescue  AnotherError  =>  error  # Здесь на объект исключения ссылается  # переменная `error ' rescue  # Это перехватывает все исключения, производные от StandardError  retry  # Это снова выполняет начальный раздел else  # Это выполняется только в том случае, если не было возбуждено никаких исключений, убедитесь  # Это всегда выполняется, исключение или не конец

S-Lang [ править ]

 пытаться  { % код, который может вызвать исключение } поймать SomeError:  {  % код, обрабатывающий это исключение } поймать SomeOtherError: {  % код, обрабатывающий это исключение } наконец% необязательный блок { % Этот код всегда будет выполняться }

Новые исключения могут быть созданы с помощью new_exceptionфункции, например,

 new_exception («MyIOError», IOError, «Моя ошибка ввода-вывода»);

создаст исключение, называемое MyIOErrorподклассом IOError. Исключения могут быть сгенерированы с помощью оператора throw, который может генерировать произвольные объекты S-Lang .

Smalltalk [ править ]

 [ "код, который может вызвать исключение" ] на:  ExceptionClass  do: [ : ex  |  «код, обрабатывающий исключение» ] .

Общий механизм обеспечивается сообщением . [6] Исключением являются только обычные объекты, подкласс , вы бросаете один путем создания экземпляра и отправить ему сообщение, например, . Механизм обработки ( ) снова представляет собой обычное сообщение, реализованное с помощью . Вызванное исключение передается в качестве параметра для закрытия блока обработки и может быть запрошено, а также потенциально отправлено ему, чтобы разрешить поток выполнения.on:do:Error#signalMyException new signal#on:do:BlockClosure#resume

Swift [ править ]

Обработка исключений поддерживается начиная со Swift 2.

enum  MyException  :  ErrorType  {  case  Foo ( String ,  Int ) } func  someFunc ()  выбрасывает  {  throw  MyException . Foo ( "недостаточно еды" ,  2 ) } do  {  попробуйте  someFunc ()  print ( "Не достигнуто" ) }  перехватите  MyException . Foo ( let  s ,  let  i )  {  print ("MyException: \ ( s ) , \ ( i ) " ) }  catch  {  print ( "Неожиданное исключение: \ ( ошибка ) " ) }

Tcl [ править ]

if  {  [  catch  {  foo } err ]  }  {  добавит  "Error: $ err" }

Начиная с Tcl 8.6, есть также команда try:

попробуйте  {  someCommandWithExceptions } на ok { res opt }  {  # обработать обычный регистр. } trap ListPattern1 { err opt }  {  # обрабатывать исключения с кодом ошибки, соответствующим ListPattern1 } trap ListPattern2 { err opt }  {  # ... } при ошибке { err opt }  {  # обрабатывать все остальное. } finally {  # запускаем все команды, которые должны выполняться после блока try. }

VBScript [ править ]

С помощью  New  Try :  On  Error  Resume  Next  'do Something (рекомендуется только одна инструкция) . Поймайте :  На  Error  GoTo  0 :  Выберите  случай  . Number  Case  0  'эта строка требуется при использовании предложения' Case Else 'из-за отсутствия ключевого слова «Is» в инструкции VBScript Case  ' без исключения  Case  SOME_ERRORNUMBER  'обработка исключений  Case  Else  ' неизвестное исключение End  Select :  End  With'*** Try Class *** Class  Try  Private  mstrDescription  Private  mlngHelpContext  Private  mstrHelpFile  Private  mlngNumber  Private  mstrSource Public  Sub  Catch ()  mstrDescription  =  Err . Описание  mlngHelpContext  =  Err . HelpContext  mstrHelpFile  =  Err . HelpFile  mlngNumber  =  Err . Число  mstrSource  =  Err . Источник  End  Sub Общедоступное  свойство  Get  Source ()  Source  =  mstrSource  End  Property  Public  Property  Get  Number ()  Number  =  mlngNumber  Конечное  свойство Общедоступное  свойство  Get  HelpFile ()  HelpFile  =  mstrHelpFile  End  Property  Общедоступное  свойство  Get  HelpContext ()  HelpContext  =  mlngHelpContext  End  Property  Общедоступное  свойство  Получить  описание ()  Description  =  mstrDescription  End  Property End  Class

[7]

Visual Basic 6 [ править ]

Синтаксис обработки исключений очень похож на базовый. Обработка ошибок локальна для каждой процедуры.

On  Error  GoTo  HandlerLabel  'При возникновении ошибки переходит к HandlerLabel, который определен в любом месте внутри Function или Sub ' или On  Error  GoTo  0  'отключает обработку ошибок. Ошибка вызывает фатальную ошибку времени выполнения и останавливает приложение «или на  Error  RESUME  Next  » Объект Err установлен, но выполнение продолжается на следующей команде. Вы по-прежнему можете использовать объект Err для проверки состояния ошибки. '... Эээ . Raise  6  'Сгенерировать ошибку «Переполнение» с помощью встроенного объекта Err. Если обработчика ошибок нет, вызывающая процедура может перехватить исключение с тем же синтаксисом '...LastLabel :  'просто общая метка внутри процедуры (неофициальная эмуляция раздела  finally на других языках) ' код очистки, всегда выполняется Exit  Sub  ' завершает  процедуру'поскольку мы находимся после оператора Exit Sub, следующий код скрыт для выполнения без ошибок HandlerLabel :  ' определяет общую метку, которая здесь используется для обработки исключений. Если  Err . Number  =  6  Тогда  "Select Case statement" обычно является лучшим решением  Resume  finallyLabel  "продолжить выполнение на определенной метке. Обычно что-то со значением «Наконец» на других языках  »или«  Возобновить  дальше »  » продолжить выполнение оператора рядом с «Err.Raise 6»  или «  Возобновить  », продолжить выполнение (повторить) оператор «Err.Raise 6» Конец,  еслиMsgBox  Err . Число  &  ""  &  Err . Источник  &  ""  &  Erl  &  ""  &  Err . Описание  &  ""  &  Err . LastDllError  'показать окно сообщения с важными свойствами ошибки  ' Erl - это глобальная переменная номера строки встроенного VB6 (если используется). Обычно используется какая-то надстройка IDE, которая помечает каждую строку кода номером перед компиляцией Resume  finallyLabel

Пример конкретной (неофициальной) реализации обработки исключений, использующей объект класса «Try».

With  New  Try :  On  Error  Resume  Next  'Создайте новый объект класса "Try" и используйте его. Затем установите этот объект по умолчанию. Может быть "Dim T As New Try: ... ... T.Catch  " do Something (рекомендуется только один оператор) . Catch :  On  Error  GoTo  0 :  Select  Case  . Number  'Вызвать процедуру Try.Catch (). Затем переключить отключение обработки ошибок. Затем используйте оператор типа switch для результата свойства Try.Number (значение свойства Err.Number встроенного объекта Err).  Случай  SOME_ERRORNUMBER  'Обработка исключения  Case  Is  <>  0 «Когда Err.Number равен нулю, никакой ошибки не произошло  » Неизвестное исключение End  Select :  End  С'*** 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  StringPublic  Sub  Catch ()  mstrDescription  =  Err . Описание  mlngHelpContext  =  Err . HelpContext  mstrHelpFile  =  Err . HelpFile  mlngLastDllError  =  Err . LastDllError  mlngNumber  =  Err . Число  mstrSource  =  Err . Источник End  SubОбщедоступное  свойство  Get  Source ()  As  String  Source  =  mstrSource End  PropertyПубличное  свойство  Получить  число ()  как  длинное  число  =  mlngNumber Конечное  свойствоОткрытое  свойство  Получить  LastDllError ()  As  Long  LastDllError  =  mlngLastDllError End  СвойствоОбщедоступное  свойство  Get  HelpFile ()  As  String  HelpFile  =  mstrHelpFile End  PropertyОбщедоступное  свойство  Get  HelpContext ()  As  Long  HelpContext  =  mlngHelpContext End  PropertyОткрытое  Property  Get  Описание ()  As  Строка  Описание  =  mstrDescription End  собственности

[7]

Visual Basic .NET [ править ]

В Tryблоке должно быть хотя бы одно предложение Catchили Finallyпредложение и не более одного Finallyпредложения.

Попробуйте  'код, который будет выполняться здесь Catch  ex  As  Exception  When  condition  ' Обработать исключение, когда определенное условие истинно. Объект исключения хранится в ex. Catch  ex  As  ExceptionType  'Обработка исключения указанного типа (например, DivideByZeroException, OverflowException и т. Д.) Catch  ex  As  Exception  ' Обработка исключения (захват всех исключений не указанного ранее типа) Catch  'Обрабатывает все, что может быть сгенерировано, включая не- Исключения CLR. Ну наконец то 'Всегда запускать при выходе из блока try (включая предложения catch), независимо от того, были ли выброшены какие-либо исключения или они были обработаны.  'Часто используется для очистки и закрытия ресурсов, которые обрабатывает такой файл.  'Не может быть запущен при вызове Environment.FailFast () и в других общесистемных исключительных условиях (например, потеря мощности) или когда процесс завершается сбоем из-за исключения в другом потоке. Конец  попытки

Визуальный пролог [ править ]

http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Try-catch-finally

попробуйте  % Block для защиты отлова  TraceId  do  % Код для выполнения в случае исключения; TraceId дает доступ к информации об исключении, наконец,  % Код будет выполняться независимо, однако другие части будут вести себя в конце  попытки

X ++ [ править ]

public  static  void  Main ( Args  _args ) {  try  {  // Код, который может  вызвать исключение. }  catch  ( Exception :: Error )  // Или любой другой тип исключения.  {  // Обработка ошибки.  }  catch  {  // Обработка любого другого типа исключения, не обработанного ранее.  } // Код здесь будет выполняться до тех пор, пока будет обнаружено любое исключение. }

Ссылки [ править ]

  1. ^ Часто задаваемые вопросы Бьярна Страуструпа
  2. ^ «Обработка исключений» . Архивировано из оригинала на 2014-01-02 . Проверено 1 января 2014 .
  3. ^ «Теги обработки исключений» . Архивировано из оригинала на 2014-01-02 . Проверено 1 января 2014 .
  4. ^ https://issues.jboss.org/browse/RAILO-2176 # Тикет системы отслеживания проблем сообщества JBoss для добавленияretry
  5. ^ Borland, Delphi версии 7.0, онлайн-справка
  6. ^ «Фарон по примеру» . Архивировано из оригинала на 2009-10-21 . Проверено 20 марта 2010 .
  7. ^ a b Try-Catch для VB

См. Также [ править ]

  • Обработка исключений для семантики обработки исключений
  • Синтаксис для определения синтаксиса в информатике