Блоки try catch finally в jscript 5


Содержание

Блоки try , catch и finally

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

Всем известно назначение блоком try , catch и finally . я вот всегда думал в чем все таки смысл блок finally , везде написано что он выполнится вне зависимости выбросит система исключение или нет , но почему б тогда не написать код без этого блока сразу после catch, простенький пример

Но ведь последняя строчка выведется и без последнего блока ? в чем жеж смысл

и тут я наткнулся вот на такую фразу

Блок finally выполнится и в том случае , если любой код в блоке try или в связанных с ним catch приведет к возврату из метода

Операторы перехода и обработка исключений

Веб-программирование — JavaScript — Операторы перехода и обработка исключений

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

Оператор return заставляет интерпретатор перейти из вызванной функции обратно в точку ее вызова и вернуть значение вызова. Оператор throw возбуждает исключение и предназначен для работы в сочетании с операторами try/catch/finally, которые определяют блок программного кода для обработки исключения. Это достаточно сложная разновидность операторов перехода: при появлении исключения интерпретатор переходит к ближайшему объемлющему обработчику исключений, который может находиться в той же функции или выше, в стеке возвратов вызванной функции.

Подробнее все эти операторы перехода описываются в следующих подразделах.

Метки инструкций

Любая инструкция может быть помечена указанным перед ней идентификатором и двоеточием:

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

Присвоив имя циклу, его затем можно использовать в инструкциях break и continue, внутри цикла для выхода из него или для перехода в начало цикла, к следующей итерации. Инструкции break и continue являются единственными инструкциями в языке JavaScript, в которых можно указывать метки — о них подробнее рассказывается далее. Ниже приводится пример инструкции while с меткой и инструкции continue, использующей эту метку:

Идентификатор, используемый в качестве метки инструкции, может быть любым допустимым идентификатором JavaScript, кроме зарезервированного слова. Имена меток отделены от имен переменных и функций, поэтому в качестве меток допускается использовать идентификаторы, совпадающие с именами переменных или функций.

Метки инструкций определены только внутри инструкций, к которым они применяются (и, конечно же, внутри вложенных в них инструкций). Вложенные инструкции не могут помечаться теми же идентификаторами, что и вмещающие их инструкции, но две независимые инструкции могут помечаться одинаковыми метками. Помеченные инструкции могут помечаться повторно. То есть любая инструкция может иметь множество меток.

Оператор break

Оператор break приводит к немедленному выходу из самого внутреннего цикла или оператора switch. Ранее мы уже видели примеры использования оператора break внутри оператора switch. В циклах он обычно используется для немедленного выхода из цикла, когда по каким-либо причинам требуется завершить выполнение цикла.

Когда цикл имеет очень сложное условие завершения, зачастую проще бывает реализовать эти условия с помощью оператора break, чем пытаться выразить их в одном условном выражении цикла. Следующий пример пытается отыскать элемент массива с определенным значением. Цикл завершается обычным образом по достижении конца массива или с помощью оператора break, как только будет найдено искомое значение:

В языке JavaScript допускается указывать имя метки за ключевым словом break (идентификатор без двоеточия):

Когда оператор break используется с меткой, она выполняет переход в конец именованной инструкции или прекращение ее выполнения. В случае отсутствия инструкции с указанной меткой попытка использовать такую форму оператора break порождает синтаксическую ошибку. Именованная инструкция не обязана быть циклом или оператором switch. Оператор break с меткой может выполнять «выход» из любой вмещающей ее инструкции. Объемлющая инструкция может даже быть простым блоком инструкций, заключенным в фигурные скобки исключительно с целью пометить его.

Между ключевым словом break и именем метки не допускается вставлять символ перевода строки. Дело в том, что интерпретатор JavaScript автоматически вставляет пропущенные точки с запятой: если разбить строку программного кода между ключевым словом break и следующей за ним меткой, интерпретатор предположит, что имелась в виду простая форма этого оператора без метки, и добавит точку с запятой.

Оператор break с меткой необходим, только когда требуется прервать выполнение инструкции, не являющейся ближайшим объемлющим циклом или оператором switch.

Оператор continue

Оператор continue схож с оператором break. Однако вместо выхода из цикла оператор continue запускает новую итерацию цикла. Синтаксис оператора continue столь же прост, как и синтаксис оператора break. Оператор continue может также использоваться с меткой.

Оператор continue, как в форме без метки, так и с меткой, может использоваться только в теле цикла. Использование его в любых других местах приводит к синтаксической ошибке. Когда выполняется оператор continue, текущая итерация цикла прерывается и начинается следующая. Для разных типов циклов это означает разное:

В цикле while указанное в начале цикла выражение проверяется снова, и если оно равно true, тело цикла выполняется с начала.

В цикле do/while происходит переход в конец цикла, где перед повторным выполнением цикла снова проверяется условие.

В цикле for вычисляется выражение инкремента и снова вычисляется выражение проверки, чтобы определить, следует ли выполнять следующую итерацию.

В цикле for/in цикл начинается заново с присвоением указанной переменной имени следующего свойства.

Обратите внимание на различия в поведении оператора continue в циклах while и for. Цикл while возвращается непосредственно к своему условию, а цикл for сначала вычисляет выражение инкремента, а затем возвращается к условию. В следующем примере показано использование оператора continue без метки для выхода из текущей итерации цикла для четных чисел:

Оператор continue, как и break, может применяться во вложенных циклах в форме, включающей метку, и тогда заново запускаемым циклом необязательно будет цикл, непосредственно содержащий оператор continue. Кроме того, как и для break, переводы строк между ключевым словом continue и именем метки не допускаются.

Оператор return

Вызов функции является выражением и подобно всем выражениям имеет значение. Оператор return внутри функций служит для определения значения, возвращаемого функцией. Оператор return может располагаться только в теле функции. Присутствие его в любом другом месте является синтаксической ошибкой. Когда выполняется оператор return, функция возвращает значение выражения вызывающей программе. Например:

Если функция не имеет оператора return, при ее вызове интерпретатор будет выполнять инструкции в теле функции одну за другой, пока не достигнет конца функции, и затем вернет управление вызвавшей ее программе. В этом случае выражение вызова вернет значение undefined. Оператор return часто является последней инструкцией в функции, но это совершенно необязательно: функция вернет управление вызывающей программе, как только будет достигнут оператор return, даже если за ним следуют другие инструкции в теле функции.

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

Оператор throw

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


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

Оператор throw имеет следующий синтаксис:

Результатом выражения может быть значение любого типа. Оператору throw можно передать число, представляющее код ошибки, или строку, содержащую текст сообщения об ошибке. Интерпретатор JavaScript возбуждает исключения, используя экземпляр класса Error одного из его подклассов, и вы также можете использовать подобный подход. Объект Error имеет свойство name, определяющее тип ошибки, и свойство message, содержащее строку, переданную функции-конструктору. Ниже приводится пример функции, которая возбуждает объект Error при вызове с недопустимым аргументом:

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

Если блок программного кода, в котором возникло исключение, не имеет соответствующей конструкции catch, интерпретатор анализирует следующий внешний блок программного кода и проверяет, связан ли с ним обработчик исключений. Это продолжается до тех пор, пока обработчик не будет найден.

Илон Маск рекомендует:  Функции платежей cybercash

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

Конструкция try/catch/finally

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

И блок catch, и блок finally не являются обязательными, однако после блока try должен обязательно присутствовать хотя бы один из них. Блоки try, catch и finally начинаются и заканчиваются фигурными скобками. Это обязательная часть синтаксиса, и она не может быть опущена, даже если между ними содержится только одна инструкция.

Следующий фрагмент иллюстрирует синтаксис и назначение конструкции try/catch/finally:

Обратите внимание, что за ключевым словом catch следует идентификатор в скобках. Этот идентификатор похож на параметр функции. Когда будет перехвачено исключение, этому параметру будет присвоено исключение (например, объект Error). В отличие от обычной переменной идентификатор, ассоциированный с оператором catch, существует только в теле блока catch.

Далее приводится более реалистичный пример конструкции try/catch. В нем вызываются метод factorial(), определенный в предыдущем примере, и методы prompt() и alert() клиентского JavaScript для организации ввода и вывода:

Если пользователь введет отрицательное число, высветится предупреждающее сообщение:

Это пример конструкции try/catch без оператора finally. Хотя finally используется не так часто, как catch, тем не менее иногда этот оператор оказывается полезным. Блок finally гарантированно исполняется, если исполнялась хотя бы какая-то часть блока try, независимо от того, каким образом завершилось выполнение программного кода в блоке try. Эта возможность обычно используется для выполнения заключительных операций после выполнения программного кода в продолжении try.

В обычной ситуации управление доходит до конца блока try, а затем переходит к блоку finally, который выполняет необходимые заключительные операции. Если управление вышло из блока try как результат выполнения операторов return, continue или break, перед передачей управления в другое место выполняется блок finally.

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

Если сам блок finally передает управление с помощью операторов return, continue, break или throw или путем вызова метода, генерирующего исключение, незаконченная команда на передачу управления отменяется и выполняется новая. Например, если блок finally сгенерирует исключение, это исключение заменит любое ранее сгенерированное исключение.

Javascript try..catch?

На клиентской части try/catch используются редко, потому ситуации с исключениями связаны с несуществующими методами/переменными/свойствами. Но если речь идет скажем о работе с файлами или еще чего такое, они могут быть полезны. Так же полезно

Я увы мало работал с серверным JS, но когда разбирался с ним, а точнее выбирал между Erlang и Node.js мне на глаза попалась статья о том, что все в Node.js надо оборачивать в try/catch. Это связано с тем, что если что-то упадет, а ситуации бывают разные, то упадет и весь сервер. А вам это точно радости не прибавит.

Как в случае браузерного, так и в случае серверного Javascript конструкция try/catch используется для отлова исключений в синхронных операциях (пример: десериализация JSON-данных или валидация данных которые ввёл пользователь). Если требуется обрабатывать ошибки в асинхронных операциях, то ошибка либо передается в callback-функцию (В Node.js общепринятым шаблоном вызова callback-функции является вызов вида callback(err, results), где лишь один из аргументов может принимать значения отличные от null.), либо в более сложных случаях генерируется событие ‘error’ объекта класса EventEmitter.

В Node.js try/catch используется очень редко (в основном только при парсинге JSON-данных), это объясняется тем что большинство операций в Node.js асинхронны, как правило ошибку передают в callback-функцию или генерируют событие «error» у объекта класса EventEmitter.

Вот пример иллюстрирующий, что try/catch не отловит исключение возникшее при выполнении асинхронной операции:

Дело в том, что исключение бросается и, соответственно , должно ловиться в том контексте, в котором вызывается функция. В данном примере try/catch и вызов функции бросающей исключение выполнятся в разных контекстах в силу асинхронности функции doSomeAsynchronousOperation.

По поводу вашего последнего тезиса, обычно какие-то специфичные фичи, которых нету в браузерах, делают через $.support, модернизер ну или, например если нам надо проверить есть ли у браузера поддержка pushState, то просто if( window.history.pushState).

Но буквально недавно у меня была проблема с методом jQuery animate — scrollTop. в IE7 постоянно валились скрипты изза ошибки на уровне jQuery, и тут try/catch пришли на помощь.

Перехват ошибок. Throw, Try и Catch

Оператор try позволяет проверить блок кода на возникновение ошибок.

Оператор catch позволяет обрабатывать возникшую ошибку.

Оператор throw позволяет генерировать пользовательские ошибки.

Оператор finally позволяет выполнять код после операторов try и catch не зависимо от результата.

Ошибки будут!

Во время выполнения кода JavaScript, могут возникать разные ошибки.

Это могут быть ошибки кодирования, сделанные программистом, ошибки, возникающие в результате ввода неверных данных, и другие непредвиденные вещи.

В следующем примере, чтобы умышленно создать ошибку, мы вместо команды alert написали adddlert:

JavaScript перехватит adddlert как ошибку и выполнит код в операторе catch, чтобы ее обработать.

Операторы try и catch

Оператор try определяет блок кода, который во время выполнения будет проверяться на возникновение ошибок.


Оператор catch определяет блок кода, который будет выполняться, если в блоке оператора try возникнет ошибка.

Операторы try и catch всегда используются в паре:

JavaScript генерирует ошибки

Когда возникает ошибка, обычно интерпретатор JavaScript останавливает выполнение кода и генерирует сообщение об ошибке.

Если говорить техническими терминами, то интерпретатор JavaScript сгенерирует исключение (сгенерирует ошибку).

На самом деле интерпретатор JavaScript создаст объект Error с двумя свойствами — name и message.

Оператор throw

Оператор throw позволяет создавать пользовательские ошибки.

В техническом смысле вы можете генерировать исключения (генерировать ошибки).

Исключения могут быть строкой, числом, логическим значением или объектом JavaScript:

Используя оператор throw вместе с try и catch, вы можете контролировать ход программы и генерировать пользовательские сообщения об ошибках.

Пример проверки ввода

В следующем примере проверяются данные ввода. Если введено неверное значение, то генерируется исключение (err).

Исключение (err) перехватывается оператором catch, и выводится пользовательское сообщение об ошибке:

HTML проверка

Приведенный выше код это всего лишь пример.

Современные браузеры часто используют комбинацию JavaScript и встроенной HTML проверки, реализуемой при помощи предопределенных правил, заданных в HTML атрибутах:

Оператор finally

Оператор finally позволяет выполнить код после операторов try и catch, независимо от результатов проверки:

Объект Error

В JavaScript есть встроенный объект Error, который предоставляет информацию по возникшей ошибке.

Объект Error предоставляет два полезных свойства:

Свойство Описание
name Устанавливает или возвращает имя ошибки
message Устанавливает или возвращает сообщение об ошибке (строку)

Значения свойства name

В свойстве name объекта Error может быть возвращено шесть различных значений:

Имя ошибки Описание
EvalError Ошибка в функции eval()
RangeError Число «за пределами диапазона»
ReferenceError Недопустимая ссылка (обращение)
SyntaxError Синтаксическая ошибка
TypeError Ошибка типов
URIError Ошибка в encodeURI()

EvalError

EvalError указывает на то, что возникла ошибка в функции eval().

В более новых версиях JavaScript никогда не генерируется ошибка EvalError. Вместо нее используется SyntaxError.

RangeError

Ошибка RangeError возникает, если вы используете число, которое выходит за пределы диапазона допустимых значений.

Например, нельзя задать число с 500 знаковыми цифрами.

ReferenceError

Ошибка ReferenceError возникает в том случае, когда вы используете (ссылаетесь) переменную, которая не была декларирована:

SyntaxError

Ошибка SyntaxError возникает, когда вы пытаетесь выполнить код с синтаксическими ошибками.

TypeError

Ошибка TypeError возникает, когда вы используете значение, выходящее за пределы диапазона ожидаемых типов:


URIError

Ошибка URIError возникает, когда вы используете недопустимые символы в функциях URI:

Нестандартные свойства объекта Error

Mozilla и Microsoft определяют ряд нестандартных свойств объекта Error:

fileName (Mozilla)
lineNumber (Mozilla)
columnNumber (Mozilla)
stack (Mozilla)
description (Microsoft)
number (Microsoft)

Никогда не используйте эти свойства в публичном веб-сайте. Они не будут работать во всех браузерах.

Перехват ошибок в JavaScript, «try..catch»

Перехват ошибок в JavaScript, «try..catch»

Здравствуйте! В этом уроке я хотел бы рассказать об ошибках в JavaScript и о том как их собственно обрабатывать. Ведь часто случается, что ошибки происходят время от времени и тут даже дело не в наличие опыта программирования или даже полном его отсутствии. Ведь и у матерых программистов тоже случаются ошибки никто от этого не застрахован.

Ошибки бывают в основном 2-х типов — это синтаксические и логические. К синтаксическим можно отнести ошибки в имени переменных, функций, ошибки в синтаксисе кода. В принципе такие ошибки легко отловить через консоль браузера.

А вот логические ошибки с ними все не так просто потому, что они приводят к неправильному выполнению кода программы. Поэтому для их устранения потребуется отладка программы, чтобы понять что собственно происходит на каждом шаге скрипта. Мы же с вами здесь рассмотрим в основном локализацию синтаксических ошибок с помощью конструкции try…catch.

Конструкция перехвата ошибок try…catch

Конструкция try..catch состит из 2-х блоков: try, и затем catch. Вот пример записи в общем виде

Работает эта конструкция таким образом:

  1. Выполняется код внутри блока try, так называемой ловушки.
  2. Если в нём не встречаются ошибки, то блок catch(err) игнорируется.
  3. А вот, если в нём возникнет ошибка, то выполнение try будет прервано на ошибке, и управление передается в начало блока catch(err). При этом переменная err (можно выбрать любое другое название) будет содержать объект ошибки с подробнейшей информацией о произошедшей ошибке.

Поэтому при ошибке в try скрипт не останавливается, и даже более того мы имеем возможность обработать ошибку внутри блока catch.

Рассмотрим это на примерах.

  • Пример без ошибок: при запуске сработают alert (1) и (2):

А вот пример с ошибкой: при запуске сработают (1) и (3):

В случае, если грубо нарушена структура кода, не закрыта фигурная скобка или где-то стоит лишняя запятая, то вам никакой try..catch не поможет. Это синтаксические ошибки, интерпретатор такой код просто не понимает.

Важное замечание try..catch может работать только в синхронном коде

Ошибку, которая может произойти в коде,который будет выполняться через время например в setTimeout, try..catch не поймает:

На момент запуска функции, назначенной через setTimeout, этот код уже завершится, и интерпретатор выйдет из блока try..catch.

Для того чтобы Чтобы поймать ошибку внутри функции из setTimeout, и try..catch должен быть в той же функции.

Объект ошибки

В примере выше мы видим объект ошибки, который вы передаете в блок catch. У него есть три основных свойства:

name Тип ошибки. Например, при обращении к переменной, которой нет: «ReferenceError». message Сообщение о деталях ошибки stack Выводит более полную информацию, с указанием строки, где произошла ошибка и саму ошибку.

Генерация своих ошибок

Оператор throw

Данный оператор throw генерирует ошибку.

Технически в качестве объекта ошибки вы можете передать что угодно, это может быть даже и не объект, а число или строка.

В качестве конструктора ошибок вы можете использовать встроенный конструктор: new Error(message) или любой другой.

В JavaScript также встроен ряд конструкторов для стандартных ошибок: SyntaxError, ReferenceError, RangeError и некоторые другие.

В данном примере мы используем конструктор new SyntaxError(message). Он создаёт ошибку того же типа, что и JSON.parse.

Получается, что блок catch – единственное место для обработки ошибок во всех случаях.

Оборачивание исключений


И, для полноты картины – последняя, техника по работе с ошибками. Она, является стандартной практикой во многих языках программирования.

Цель функции readData в примере выше – это прочитать данные. При этом чтении могут возникать различные ошибки, не только SyntaxError, но и, возможно, к примеру URIError и другие.

Код, который вызвает readData, хотел бы иметь конечно либо результат, либо информацию об ошибке.

При этом очень важным является следующий вопрос: обязан ли этот внешний код знать о типах ошибок, которые возникают при чтении данных, и конечно же уметь перехватывать их?

В данном случае, если при чтении данных происходит ошибка, то будем генерировать её в виде объекта ReadError, с сообщением. А «исходную» ошибку на всякий случай тоже сохраним, присвоим в свойство cause.

Выглядит это так:

Этот подход называют «оборачиванием» исключения, поскольку мы берём ошибки «более низкого уровня» и «заворачиваем» их в ReadError, которая соответствует текущей задаче.

Секция finally

В конструкции try..catch есть и ещё один блок: finally.

Выглядит этот расширенный синтаксис так:

Секция finally не обязательна, но если есть, то она будет выполнена всегда, независимо от того были ошибки или нет:

  • после блока try, в случае если ошибок не было,
  • после catch, в случае если они были.

Попробуйте запустить такой код?

У него 2 варианта работы:

  1. Если вы ответите на вопрос «сгенерировать ошибку?» утвердительно, то try -> catch -> finally.
  2. Если ответите отрицательно, то try -> finally.

Секцию finally используют, чтобы завершить начатые операции при любом варианте развития событий.

Последняя надежда: window.onerror

Допустим, ошибка произошла вне блока try..catch или выпала из try..catch наружу, во внешний код. Скрипт перестал работать.

Можно ли как-то узнать о том, что произошло? Да можно.

В браузере есть специальное свойство window.onerror, если в него записать функцию, то она выполнится и получит в аргументах сообщение ошибки, текущий URL и номер строки, откуда «выпала» ошибка.

Необходимо лишь позаботиться, чтобы функция была назначена заранее.

Как правило, роль window.onerror заключается не в том, чтобы оживить скрипт – скорее всего, это уже невозможно, а в том, чтобы отослать сообщение об ошибке на сервер, где разработчики о ней узнают.
Существуют даже специальные веб-сервисы, которые предоставляют скрипты для отлова и аналитики таких ошибок, например: https://errorception.com/ и http://www.muscula.com/.

Итого

Обработка ошибок – это очень полезная и важная тема.

В JavaScript для этого используют следующие методы:

  • Конструкция try..catch..finally – позволяет обработать ошибку в скрипте, как бы локализовать область с ошибкой.
  • Возможны также и другие варианты try..catch или try..finally.
  • Для генерации пользовательской ошибки используется оператор throw err.

Есть также и другие интересные приемы:

  • Проброс исключения – catch(err) обрабатывает только те ошибки, которые вы хотели бы в нём увидеть, а вот остальные – пробрасывать дальше через throw err. Определить, нужная ли это ошибка, можно, по свойству name.
  • Оборачивание исключений – эта некая функция, которая позволяет обернуть исключения и пробросить их дальше.
  • В window.onerror можно присвоить специальную функцию, которая выполнится при любой ошибке.

Задача

Сравните два фрагмента кода.


  1. Первый использует finally для выполнения кода по выходу из try..catch:

Второй фрагмент просто ставит очистку ресурсов за try..catch:

Нужно, чтобы код финализации всегда выполнялся при выходе из блока try..catch и, таким образом, заканчивал начатую работу. Имеет ли здесь finally какое-то преимущество или оба фрагмента работают одинаково?

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

JavaScript — Обработка исключений

На этом уроке мы познакомимся с оператором обработки исключений try. catch , который предназначен для перехвата ошибок в некотором блоке кода и их обработки.

Применение оператора try. catch

Оператор обработки исключений try. catch обычно применяется в следующих ситуациях:

  • Для некоторого участка кода, в котором может возникнуть ошибка;
  • Для валидации (проверки) данных перед отправкой на сервер;
  • Для использования в сложных случаях при написании кроссбраузерных приложений.

Теперь давайте рассмотрим, что же произойдет в сценарии на JavaScript при возникновении ошибки и для чего нужен оператор try. catch .

Если в сценарии на языке JavaScript появится ошибка, то дальнейшее выполнение программы будет прекращено. Т.е. инструкции (операторы), которые идут после ошибки выполняться не будут. Но если нам необходимо выполнение программы не прерывать, а переходить к следующей инструкции после той, где может возникнуть ошибка, то эту инструкцию необходимо заключить в оператор » try. catch «.

Синтаксис оператора try. catch

Принцип работы с оператором try. catch заключается в следующем:

Блок, в котором могут возникнуть ошибки, мы обрамляем фигурными скобками, и перед ним пишем ключевое слово try (с англ. попробовать). После этого блока пишем ключевое слово catch (с англ. поймать, ловить) и в круглых скобках указываем переменную, в которой будем хранить информацию об ошибке. Далее фигурными скобками обрамляем блок, предназначенный для обработки ошибок.

Принцип работы оператора try. catch

Оператор обработки исключений работает следующим образом:

Сначала он пытается выполнить все инструкции (операторы), указанные в блоке try . Если внутри блока try ошибки не возникает, то блок catch просто игнорируется, т.е. он не выполняется. В том случае если внутри блока try возникает ошибка, то оставшиеся операторы в этом блоке будут проигнорированы (т.е. они выполняться не будут) и сразу же начнут выполняться операторы внутри блока catch . Самое главное то, что инструкции, идущие после оператора try. catch , продолжат выполняться и работа программы не остановится.

В результате выполнения кода в 4 строчке произойдет ошибка, т.к. оператор documant браузером будет не определён. В этом случае 5 строчка браузером выполнена не будет, т.к. начнут выполняться операторы в блоке catch . В качестве параметра блока catch определим переменную e , в которой будет хранить информацию об ошибке. Данную переменную мы будем использовать в операторе alert для вывода сообщения об ошибке.

Блок finally

У оператора обработки исключений есть ещё один блок, который называется finally . Данный блок является не обязательным, и его можно использовать только при необходимости. Он не имеет параметров и в отличие от блока catch выполняется всегда, вне зависимости от того возникла ошибка или нет.

Но так как инструкции, идущие после оператора try. catch тоже выполняются всегда, то возникает вопрос: «Зачем нужен блок finally?»

На самом деле, инструкции, идущие после try. catch , выполняются не всегда. Это может произойти только в том случае, если произойдет ошибка в блоке catch . Когда это произойдёт, программа приостановит своё выполнение и операторы, идущие после конструкции try. catch выполняться не будут. Единственный блок инструкций (операторов), который будет выполняться – это блок finally .

В результате выполнения кода оператор alert , идущий после конструкции try. catch так и не будет выполнен.

Блоки try catch finally в jscript 5

5.6.6. Инструкция try/catch/finally

Инструкция try/catch/finally реализует механизм обработки исключений в JavaScript. Конструкция try в этой инструкции просто определяет блок кода, в котором обрабатываются исключения. За блоком try следует конструкция catch с блоком инструкций, вызываемых, если где-либо в блоке try возникает исключение. За конструкцией catch следует блок finally , содержащий программный код, выполняющий заключительные операции, который гарантированно выполняется независимо от того, что происходит в блоке try . И блок catch , и блок finally не являются обязательными, однако после блока try должен обязательно присутствовать хотя бы один из них. Блоки try, catch и finally начинаются и заканчиваются фигурными скобками. Это обязательная часть синтаксиса, и она не может быть опущена, даже если между ними содержится только одна инструкция.

Следующий фрагмент иллюстрирует синтаксис и назначение инструкции try/catch/finally :

try <
// Обычно этот код без сбоев работает от начала до конца.
// Но в какой-то момент в нем может быть сгенерировано исключение
// либо непосредственно с помощью инструкции throw, либо косвенно —
// вызовом метода, генерирующего исключение.
>
catch (е) <
// Инструкции в этом блоке выполняются тогда и только тогда, когда в блоке try
// возникает исключение. Эти инструкции могут использовать локальную переменную е,
// ссылающуюся на объект Error или на другое значение, указанное в инструкции throw.
// Этот блок может либо некоторым образом обработать исключение, либо
// проигнорировать его, делая что-то другое, либо заново сгенерировать
// исключение с помощью инструкции throw.
>
finally <
// Этот блок содержит инструкции, которые выполняются всегда, независимо от того,
// что произошло в блоке try. Они выполняются, если блок try завершился:
// 1) как обычно, достигнув конца блока
// 2) из-за инструкции break, continue или return
// 3) с исключением, обработанным приведенным в блоке catch выше
// 4) с неперехваченным исключением, которое продолжает свое
// распространение на более высокие уровни
>

Обратите внимание, что за ключевым словом catch следует идентификатор в скобках. Этот идентификатор похож на параметр функции. Когда будет перехвачено исключение, этому параметру будет присвоено исключение (например, объект Error ). В отличие от обычной переменной идентификатор, ассоциированный с конструкцией catch , существует только в теле блока catch .

Далее приводится более реалистичный пример инструкции try/catch . В нем вызываются метод factorial(), определенный в предыдущем разделе, и методы prompt() и alert() клиентского JavaScript для организации ввода и вывода:

try <
// Запросить число у пользователя
var n = Number(prompt(«Введите положительное число»,»»));
// Вычислить факториал числа, предполагая, что входные данные корректны
var f = factorial(n);
// Вывести результат
alert(n + «! = » + f);
>
catch (ex) < // Если данные некорректны, управление будет передано сюда
alert(ех); // Сообщить пользователю об ошибке
>

Это пример инструкции try/catch без конструкции finally . Хотя finally используется не так часто, как catch , тем не менее иногда эта конструкция оказывается полезной. Однако ее поведение требует дополнительных объяснений. Блок finally гарантированно исполняется, если исполнялась хотя бы какая-то часть блока try , независимо от того, каким образом завершилось выполнение программного кода в блоке try . Эта возможность обычно используется для выполнения заключительных операций после выполнения программного кода в предложении try .

В обычной ситуации управление доходит до конца блока try , а затем переходит к блоку finally , который выполняет необходимые заключительные операции. Если управление вышло из блока try как результат выполнения инструкций return , continue или break , перед передачей управления в другое место выполняется блок finally .

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

Если сам блок finally передает управление с помощью инструкции return , continue , break или throw или путем вызова метода, генерирующего исключение, незаконченная команда на передачу управления отменяется и выполняется новая. Например, если блок finally сгенерирует исключение, это исключение заменит любое ранее сгенерированное исключение. Если в блоке finally имеется инструкция return , произойдет нормальный выход из метода, даже если генерировалось исключение, которое не было обработано.


Конструкции try и finally могут использоваться вместе без конструкции сatch . В этом случае блок finally — это просто набор инструкций, выполняющих заключительные операции, который будет гарантированно выполнен независимо от наличия в блоке try инструкции break , continue или return . Напомню, из-за различий в работе инструкции continue в разных циклах невозможно написать цикл while , полностью имитирующий работу цикла for . Однако если добавить инструкцию try/finally , можно написать цикл while , который будет действовать точно так же, как цикл for , и корректно обрабатывать инструкцию continue :

// Имитация цикла for( инициализация ; проверка ; инкремент ) тело цикла;
инициализация ;
while( проверка ) <
try
finally
>

Arguments

Required. Statements where an error can occur.

Required. Any variable name. The initial value of exception is the value of the thrown error.

Optional. Statements to handle errors occurring in the associated tryStatements.

Optional. Statements that are unconditionally executed after all other error processing has occurred.

Remarks

The try. catch. finally statement provides a way to handle some or all of the possible errors that may occur in a given block of code, while still running code. If errors occur that the programmer has not handled, JScript simply provides its normal error message to a user, as if there was no error handling.

The tryStatements contain code where an error can occur, while catchStatements contain the code to handle any error that does occur. If an error occurs in the tryStatements, program control is passed to catchStatements for processing. The initial value of exception is the value of the error that occurred in tryStatements. If no error occurs, catchStatements are never executed.

If the error cannot be handled in the catchStatements associated with the tryStatements where the error occurred, use the throw statement to propagate, or rethrow, the error to a higher-level error handler.

After all statements in tryStatements have been executed and any error handling has occurred in catchStatements , the statements in finallyStatements are unconditionally executed.

Notice that the code inside finallyStatements is executed even if a return statement occurs inside the try or catch blocks, or if the catch block re-throws the error. finallyStatments are guaranteed to always run, unless an unhandled error occurs (for example, causing a run-time error inside the catch block).

Example

The following example shows how JScript exception handling works.

try-catch-finally (Справочник по C#) try-catch-finally (C# Reference)

Чаще всего catch и finally применяются вместе для получения и использования ресурсов в блоке try , устранения исключительных обстоятельств в блоке catch и освобождения ресурсов в блоке finally . A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.

Дополнительные сведения и примеры повторного создания исключений см. в разделах try-catch и Порождение исключений. For more information and examples on re-throwing exceptions, see try-catch and Throwing Exceptions. Дополнительные сведения о блоке finally см. в разделе try-finally. For more information about the finally block, see try-finally.

Пример Example

Спецификация языка C# C# language specification

Дополнительные сведения см. в разделе Оператор try в документации Спецификация C# 6.0. For more information, see The try statement section of the C# language specification.

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

Конструкция try..catch..finally

Иногда при выполнении программы возникают ошибки, которые трудно предусмотреть или предвидеть, а иногда и вовсе невозможно. Например, при передачи файла по сети может неожиданно оборваться сетевое подключение. такие ситуации называются исключениями . Язык C# предоставляет разработчикам возможности для обработки таких ситуаций. Для этого в C# предназначена конструкция try. catch. finally .

При использовании блока try. catch..finally вначале выполняются все инструкции в блоке try . Если в этом блоке не возникло исключений, то после его выполнения начинает выполняться блок finally . И затем конструкция try..catch..finally завершает свою работу.

Если же в блоке try вдруг возникает исключение, то обычный порядок выполнения останавливается, и среда CLR начинает искать блок catch , который может обработать данное исключение. Если нужный блок catch найден, то он выполняется, и после его завершения выполняется блок finally.

Если нужный блок catch не найден, то при возникновении исключения программа аварийно завершает свое выполнение.

Рассмотрим следующий пример:

В данном случае происходит деление числа на 0, что приведет к генерации исключения. И при запуске приложения в режиме отладки мы увидим в Visual Studio окошко, которое информирует об исключении:

В этом окошке мы видим, что возникло исключение, которое представляет тип System.DivideByZeroException , то есть попытка деления на ноль. С помощью пункта View Details можно посмотреть более детальную информацию об исключении.

И в этом случае единственное, что нам остается, это завершить выполнение программы.

Чтобы избежать подобного аварийного завершения программы, следует использовать для обработки исключений конструкцию try. catch. finally . Так, перепишем пример следующим образом:

В данном случае у нас опять же возникнет исключение в блоке try, так как мы пытаемся разделить на ноль. И дойдя до строки

выполнение программы остановится. CLR найдет блок catch и передаст управление этому блоку.

После блока catch будет выполняться блок finally.

Таким образом, программа по-прежнему не будет выполнять деление на ноль и соответственно не будет выводить результат этого деления, но теперь она не будет аварийно завершаться, а исключение будет обрабатываться в блоке catch.

Следует отметить, что в этой конструкции обязателен блок try . При наличии блока catch мы можем опустить блок finally:

И, наоборот, при наличии блока finally мы можем опустить блок catch и не обрабатывать исключение:

Однако, хотя с точки зрения синтаксиса C# такая конструкция вполне корректна, тем не менее, поскольку CLR не сможет найти нужный блок catch, то исключение не будет обработано, и программа аварийно завершится.

Обработка исключений и условные конструкции

Ряд исключительных ситуаций может быть предвиден разработчиком. Например, пусть программа предусматривает ввод числа и вывод его квадрата:

Если пользователь введет не число, а строку, какие-то другие символы, то программа выпадет в ошибку. С одной стороны, здесь как раз та ситуация, когда можно применить блок try..catch , чтобы обработать возможную ошибку. Однако гораздо оптимальнее было бы проверить допустимость преобразования:

Метод Int32.TryParse() возвращает true , если преобразование можно осуществить, и false — если нельзя. При допустимости преобразования переменная x будет содержать введенное число. Так, не используя try. catch можно обработать возможную исключительную ситуацию.

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

Илон Маск рекомендует:  Wap и asp часть i
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL