Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программмная обработка исключительных ситуаций, учимся отделять мух от котлет 
:(
    Опции темы
Се ля ви
Дата 5.1.2005, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Зачем JS-кодеру может понадобиться обрабатывать ошибки в сценариях? В принципе, не существует задач, при решении которых без механизма исключений никак нельзя было бы обойтись. Однако часто их использование оказывается заметно удобнее бесконечных if`ов - поскольку в коде мы с их помощью изолируем себя от некоторых ситуаций, в которых программа должна вести себя по-другому (главным образом, это может быть связано с неадекватной работой пользователя, например, при вводе данных) - и сосредотачиваемся на описании алгоритма в случае нужных нам условий, а уже потом отдельно разбираться, как говорится, с косяками. Это как в жизни - мы часто отодвигаем проблемы на потом, просто помним, что они у нас есть, и когда будет время - мы их решим, в противовес if`овому подходу, когда мы всё время должны решать проблемы реакции на неадекватные зигзаги сценария не отходя от кассы. По себе могу сказать, что писать сложный код так намного удобней - и более того, по мере усложнения кода использование исключений становится всё более и более необходимым. А если забыть обработать какое-то исключение, заявленное при написании "чистого" кода - браузер об этом скорее всего напомнит при тестировании. smile


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

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

По сути, на уровне кода обработка исключений очень похожа на обработку событий - если сопоставить объекту Error объект event, то всё довольно быстро встанет на свои места - если код вызывает ошибку, происходит специфическое событие - исключение - его параметры записываются в специальный объект и он передаётся обработчику, который его обрабатывает.


Для тех, кто знаком с механизмом исключений в Java
Здесь я кратко приведу различия между реализацией исключений в Java и JavaScript - пропустите этот раздел если с Java вы не знакомы.

Главное отличие от Java-реализации состоит в  отсутствии (в силу не классовой, а прототипной реализации ООП) возможности использовать множественный оператор catch, основанный на наследовании и восходящем преобразовании. Здесь оператор catch может быть только один для каждого try`я. Этот приём можно менее изящно реализовать в обработчике на основе оператора switch.

Блок finally присутствует, но здесь он нужен ещё реже. Сам я, работая с JavaScript, ни разу не сталкивался с ситуацией, где бы он мне понадобился или был удобен - поэтому здесь я о нём тихонько умолчу, тоьлко намекнув, что он, в принципе, здесь есть...

Ну и, конечно, нет великолепной возможности (отсутствующей даже в C#) Java, обязывающей указывать возможность вызова исключения функцией при её описании с помощью ключевого слова throws, отсутствие какового сулит обернуться большой путаницей при использовании больших сторонних библиотек...


Объект исключения
Обычно в качестве объекта исключения выступает объект Error, хотя, строго говоря, конструкция throw может передавать абсолютно любой объект (!), который может быть принят оператором catch и соответственно обработан.

К сожалению, и область обработки исключительных ситуаций задела браузерная война - боевые действия в этой области привели к тому, что объекты Error в ECMAScript и в JScript практически не имеют ничего общего.

Какую информацию о состоянии может в себе нести исключение? По большому счёту всего 2 поля - некое название, характеризующие тип исключения, и сообщение, уточняющее особенности конкретного исключения в данном случае - если пользователь возбуждает исключение сам, то он придумывает сообщение сам, если его генерирует система - то уже она решает, какое сообщение писать. Прибавим к этим 2-м свойствам 3-е - prototype, для возможности изменять его характеристики ОО-средствами и 4-е стандартное toString() - и получим объект исключения от ECMAScript, в котором название называется "name" (в случае пользовательских объектов оно содержит строку "Error", а в случае ошибки браузера - название из небольшого списка, представленного в следующей таблице), а строка сообщения - свойство "message". Конструктор исключения от ECMAScript выглядит так: 
Код
new Error(message);


У Microsoft вместо имени у ошибки появляется составной номер (свойство "number"), состоящий из кода источника ошибки (facility code) и номера самой ошибки (что бы выделить номер источника, можно воспользоваться конструкцией 
Код
(e.number >> 16) & 0x1FFF
, а что бы выделить код самой ошибки - конструкцией 
Код
e.number & 0xFFFF
, где e - объект Error), и "description", полностью аналогичное свойству "message" в ECMAScript (начиная с IE 5.5 значение свойства "description" доступно и через свойство "message", т.е. по существу, они - синонимы, ссылающиеся на одно и то же значение). Соответствие номеров описаниям для JScript можно найти в этой таблице.
Конструктор объекта исключения от Microsoft IE выглядит так:
Код
new Error(errorNumber, message)
 - этот формат не совместим с приведённым ранее форматом, соответственно, к сожалению, для различных браузеров придётся писать разные возбуждения исключений...

Впрочем, популярный особенно в Linux-среде open-source`ный браузер Mozilla так же нередко расширяет стандарты (хотя существующие - поддерживает, в отличае от IE). В объекте Error для этого браузера добавлено 2 интересных свойства для локализации исключения - "fileName" и "lineNumber", хранящие, соответственно, информацию о файле, где произошла ошибка (актуально, когда в проекте много *.js - файлов и непонятно в котором из них ошибка) и о номере строки в этом файле.


Пример использования
Теперь давайте перейдём к практике. Для отлова исключений используется блок try..catch, выглядит это примерно так:
Код
try {
  оператор1
}
catch (исключение) {
  оператор2
}

где: оператор1 - оператор или их группа, где может быть вызвано исключение, оператор2 - обработчик исключения, исключение - обычно объект Error, характеризующий исключение и передаваемый оператору2.

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

Теперь о самостоятельном вызове с помощью оператора throw. Как и в других темах, существует 2 способа писать универсальный код:
1) Различать браузеры и писать разный код для разных браузеров, и
2) Писать более простой код, который относится к области пересечения браузеров.
Я нахожу более мудрым второй способ и по возможности стараюсь использовать его. В данном случае это означает, что лучше отказаться от объекта Error из-за разного синтаксиса конструкторов и присваивать исключению простую строку:
Код
function getMonthName(month) {
  month = month - 1; // Переводим month в индекс массива (1=январь, 12=декабрь)
  var months=["январь","февраль","март","апрель","май","июнь","июль",
     "август","сентябрь","октябрь","ноябрь","декабрь"];
  if (months[month] != null)
    return months[month];
  else
    throw "Неверный месяц";
}

try {
  monthName = getMonthName(myMonth); // возможно исключение
}
catch (e) {
  monthName="неизвестно";
}
document.write(monthName);



Ссылки по теме для более глубокого изучения:
1) Ю.С. Лукач, "Справочник Web-разработчика", раздел "Обработка исключений";
2) Степанищев Евгений: Блоки try... catch... finally... в JScript 5. Статья на сайте CitForum.ru 

Это сообщение отредактировал(а) Се ля ви - 22.1.2008, 14:40


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
Sardar
Дата 5.1.2005, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата
с помощью ключевого слова throwable

На самом деле throws <список экзепшенов>
Цитата
боевые действия в этой области привели к тому, что объекты Error в ECMAScript и в JScript практически не имеют ничего общего.

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

Сам использую исключения в случая когда хочу остановить скрипт, мол так плохо, дальше уже некуда smile Поэтому никогда исключения не ловлю.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Се ля ви
Дата 5.1.2005, 02:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Цитата(Sardar @ 5.1.2005, 02:23)
На самом деле throws <список экзепшенов>

Спасибо, я уже исправил :-)

Цитата(Sardar @ 5.1.2005, 02:23)
Сам использую исключения в случая когда хочу остановить скрипт, мол так плохо, дальше уже некуда Поэтому никогда исключения не ловлю.

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


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
Sardar
Дата 26.2.2007, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(Се ля ви @  5.1.2005,  00:28 Найти цитируемый пост)
Ну и, конечно, нет великолепной возможности (отсутствующей даже в C#!!!) Java, обязывающей указывать возможность вызова исключения функцией при её описании с помощью ключевого слова throws, что сулит большую путаницу при использовании больших библиотек...

Это так называемые checked exceptions, которые физически не реализовать в окружении с динамическими типами. При отсутствии типов также не нужны множественные catch. Можно конечно сопоставлять конструктору, но он может измениться при полной замене прототипа у конструктора (да это бред, читаем это).

Поднимаю тему из небытия для грамотного и аргументированного обсуждения "Обработки исключений в JavaScript согласно ECMA-262 и диалектами". Результаты дискуссии будут собраны до статьи в VingradWiki.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Се ля ви
Дата 27.2.2007, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Декоративно подправил - орфографию, некоторые формулировки сделал чётче...


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1324 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.