Как сделать исключение
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Для этого в JavaScript есть замечательная конструкция try..catch .
Конструкция try…catch
Конструкция try..catch состоит из двух основных блоков: try , и затем catch :
Работает она так:
Выполняется код внутри блока try .
Если в нём ошибок нет, то блок catch(err) игнорируется, то есть выполнение доходит до конца try и потом прыгает через catch .
Если в нём возникнет ошибка, то выполнение try на ней прерывается, и управление прыгает в начало блока catch(err) .
При этом переменная err (можно выбрать и другое название) будет содержать объект ошибки с подробной информацией о произошедшем.
Посмотрим это на примерах.
Пример без ошибок: при запуске сработают alert (1) и (2) :
Пример с ошибкой: при запуске сработают (1) и (3) :
Если грубо нарушена структура кода, например не закрыта фигурная скобка или где-то стоит лишняя запятая, то никакой try..catch здесь не поможет. Такие ошибки называются синтаксическими, интерпретатор не может понять такой код.
Здесь же мы рассматриваем ошибки семантические, то есть происходящие в корректном коде, в процессе выполнения.
На момент запуска функции, назначенной через setTimeout , этот код уже завершится, интерпретатор выйдет из блока try..catch .
Чтобы поймать ошибку внутри функции из setTimeout , и try..catch должен быть в той же функции.
Объект ошибки
В примере выше мы видим объект ошибки. У него есть три основных свойства:
В зависимости от браузера у него могут быть и дополнительные свойства, см. Error в MDN и Error в MSDN.
Пример использования
В JavaScript есть встроенный метод JSON.parse(str), который используется для чтения JavaScript-объектов (и не только) из строки.
Обычно он используется для того, чтобы обрабатывать данные, полученные по сети, с сервера или из другого источника.
Мы получаем их и вызываем метод JSON.parse , вот так:
Более детально формат JSON разобран в главе Формат JSON, метод toJSON.
Устроит ли нас такое поведение? Конечно нет!
Получается, что если вдруг что-то не так с данными, то посетитель никогда (если, конечно, не откроет консоль) об этом не узнает.
Бывают ситуации, когда без try..catch не обойтись, это – одна из таких.
Используем try..catch , чтобы обработать некорректный ответ:
Генерация своих ошибок
Представим на минуту, что данные являются корректным JSON… Но в этом объекте нет нужного свойства name :
Вызов JSON.parse выполнится без ошибок, но ошибка в данных есть. И, так как свойство name обязательно должно быть, то для нас это такие же некорректные данные, как и "Has Error" .
Для того, чтобы унифицировать и объединить обработку ошибок парсинга и ошибок в структуре, мы воспользуемся оператором throw .
Оператор throw
Оператор throw генерирует ошибку.
Технически в качестве объекта ошибки можно передать что угодно, это может быть даже не объект, а число или строка, но всё же лучше, чтобы это был объект, желательно – совместимый со стандартным, то есть чтобы у него были как минимум свойства name и message .
В качестве конструктора ошибок можно использовать встроенный конструктор: new Error(message) или любой другой.
В JavaScript встроен ряд конструкторов для стандартных ошибок: SyntaxError , ReferenceError , RangeError и некоторые другие. Можно использовать и их, но только чтобы не было путаницы.
В данном случае мы используем конструктор new SyntaxError(message) . Он создаёт ошибку того же типа, что и JSON.parse .
Получилось, что блок catch – единое место для обработки ошибок во всех случаях: когда ошибка выявляется при JSON.parse или позже.
Проброс исключения
В коде выше мы предусмотрели обработку ошибок, которые возникают при некорректных данных. Но может ли быть так, что возникнет какая-то другая ошибка?
Конечно, может! Код – это вообще мешок с ошибками, бывает даже так, что библиотеку выкладывают в открытый доступ, она там 10 лет лежит, её смотрят миллионы людей и на 11-й год находятся опаснейшие ошибки. Такова жизнь, таковы люди.
Ошибку, о которой catch не знает, он не должен обрабатывать.
В примере ниже catch обрабатывает только ошибки SyntaxError , а остальные – выбрасывает дальше:
В примере выше try..catch внутри readData умеет обрабатывать только SyntaxError , а внешний – все ошибки.
Оборачивание исключений
И, для полноты картины – последняя, самая продвинутая техника по работе с ошибками. Она, впрочем, является стандартной практикой во многих объектно-ориентированных языках.
Цель функции readData в примере выше – прочитать данные. При чтении могут возникать разные ошибки, не только SyntaxError , но и, возможно, к примеру URIError (неправильное применение функций работы с URI) да и другие.
Код, который вызвал readData , хотел бы иметь либо результат, либо информацию об ошибке.
При этом очень важным является вопрос: обязан ли этот внешний код знать о всевозможных типах ошибок, которые могут возникать при чтении данных, и уметь перехватывать их?
Это важнейший общий подход к проектированию – каждый участок функциональности должен получать информацию на том уровне, который ей необходим.
Мы его видим везде в грамотно построенном коде, но не всегда отдаём себе в этом отчёт.
Выглядит это так:
Секция finally
Конструкция try..catch может содержать ещё один блок: finally .
Выглядит этот расширенный синтаксис так:
Секция finally не обязательна, но если она есть, то она выполняется всегда:
- после блока try , если ошибок не было,
- после catch , если они были.
Попробуйте запустить такой код?
У него два варианта работы:
Секцию finally используют, чтобы завершить начатые операции при любом варианте развития событий.
Например, мы хотим подсчитать время на выполнение функции sum(n) , которая должна возвратить сумму чисел от 1 до n и работает рекурсивно:
Здесь секция finally гарантирует, что время будет подсчитано в любых ситуациях: при ошибке в sum или без неё.
Вы можете проверить это, запустив код с указанием n=100 – будет без ошибки, finally выполнится после try , а затем с n=100000 – будет ошибка из-за слишком глубокой рекурсии, управление прыгнет в finally после catch .
Блок finally срабатывает при любом выходе из try..catch , в том числе и return .
В примере ниже из try происходит return , но finally получает управление до того, как контроль возвращается во внешний код.
Если внутри try были начаты какие-то процессы, которые нужно завершить по окончании работы, то в finally это обязательно будет сделано.
Кстати, для таких случаев иногда используют try..finally вообще без catch :
В примере выше try..finally вообще не обрабатывает ошибки. Задача в другом: выполнить код при любом выходе из try – с ошибкой ли, без ошибок или через return .
Последняя надежда: window.onerror
Допустим, ошибка произошла вне блока try..catch или выпала из try..catch наружу, во внешний код. Скрипт упал.
Можно ли как-то узнать о том, что произошло? Да, конечно.
Необходимо лишь позаботиться, чтобы функция была назначена заранее.
Итого
Обработка ошибок – большая и важная тема.
В JavaScript для этого предусмотрены:
Конструкция try..catch..finally – она позволяет обработать произвольные ошибки в блоке кода.
Это удобно в тех случаях, когда проще сделать действие и потом разбираться с результатом, чем долго и нудно проверять, не упадёт ли чего.
Полный вид конструкции:
Возможны также варианты try..catch или try..finally .
Оператор throw err генерирует свою ошибку, в качестве err рекомендуется использовать объекты, совместимые с встроенным типом Error, содержащие свойства message и name .
Кроме того, мы рассмотрели некоторые важные приёмы:
Проброс исключения – catch(err) должен обрабатывать только те ошибки, которые мы рассчитываем в нём увидеть, остальные – пробрасывать дальше через throw err .
Определить, нужная ли это ошибка, можно, например, по свойству name .
Задачи
Eval-калькулятор с ошибками
Напишите интерфейс, который принимает математическое выражение (в prompt ) и выводит результат его вычисления через eval .
Ошибкой считается не только некорректное выражение, такое как 2+ , но и выражение, возвращающее NaN , например 0/0 .
Содержание статьи:
Вступление
Часто во время выполнения программ возникают ошибки, которые не связаны с плохим написанием кода. Например, программе нужно найти пользователя, который отсутствует в базе данных, или подключенный файл оказался поврежденным.
Некоторые из ошибок происходят случайным образом и их невозможно предвидеть. Их называют исключениями.
В таблице ниже перечислим несколько свойств.
Свойство | Функция |
InnerException | Выдача экземпляра класса, вызвавшего исключение |
Source | Указание на имя объекта, который вызвал исключение |
Message | Текст ошибки |
HelpLink | Ссылка на файл справки, связанный с исключениями. |
Если нужно обработать только определенные ошибки, используют конкретный тип исключений.
Давайте рассмотрим несколько наиболее популярных.
Тип исключения | Значение |
ArgumenOutOfRangeException | Значение аргумента не соответствует допустимому диапазону |
IndexOutOfRangeException | Выход за диапазон массива или допустимых значений |
StackOverflowException | Переполнение стека |
OutOfMemoryException | Недостаточно памяти для выполнения программы |
NullReferenceException | Обращение к неопределенному объекту |
Обработку разных типов можно разграничить. Для этого каждый тип прописывают в отдельном блоке catch . Здесь важно помнить о приоритетности выполнения, так как предложения catch будут срабатывать в порядке написания.
Если менее конкретные исключения будут записаны перед более конкретными, то компилятор может выдать ошибку из-за невозможности достигнуть следующего блока.
Используя блоки try , catch и finally сначала выполняются команды в блоке try . Когда исключений нет, программа сразу переходит к блоку finally (если он есть) и часть программы, которая отвечает за обработку исключений, завершается.
Когда в блоке try произошла ошибка, то выполнение программы приостанавливается, а общеязыковая исполняющая среда (CLR) производит поиск блока catch . Если блок найден, то после его выполнения идет блок finally . В другом случае программа аварийно завершит работу.
Например, в случае деления на 0, возникает исключение System.DivideByZeroException . Чтобы не возникало таких ошибок, в блоке catch прописываем инструкцию, как указано в примере кода. Алгоритм не будет делить на 0 и выводить результаты, а программа аварийно завершается.
Ошибки в приложениях с визуальным интерфейсом
Все вышеуказанные правила работают в консольных приложениях. Если в программы есть интерфейс, то при возникновении ошибки увидим соответствующее окно:
Пример ошибки в Microsoft Visual Studio
В таком случае разработчик может попробовать продолжить выполнение программы, прервать его или изменить настройки и обработать исключение.
Генерирование исключительных ситуаций
Фильтры и условные конструкции
Метод Int32.TryParse выдаст значение true , если тип возможно преобразовать. Таким образом для этого типа ошибок необязательно применять try / catch .
В заключение
Исключения (Exceptions) это тип ошибки, которая происходит при выполнении приложения. Ошибки обычно означают появление неожиданных проблем. Тогда как исключения, обработка которых организована в коде, являются ожидаемыми, они происходят в коде приложений по различным причинам.
Исключения позволяют передать управление из одной части кода в другую часть. Когда срабатывает/выбрасывается исключение (exception thrown), текущий поток выполнения кода секции try прерывается, и запускается выполнение секции catch.
try – блок try инкапсулирует проверяемый на исключение регион кода. Если любая строка кода в этом блоке вызывает срабатывание исключения, то исключение будет обработано соответствующим блоком catch.
catch – когда происходит исключение, запускается блок кода catch. Это то место, где можно обработать исключения и предпринять адекватные для него действия, например записать событие ошибки в лог, прервать работу программы, или может просто игнорировать исключение (когда блок catch пустой).
finally – блок finally позволяет выполнить какой-то определенный код приложения, если исключение сработало, или если оно не сработало.
Часто блок finally опускается, когда обработка исключения подразумевает нормальное дальнейшее выполнение программы – потому блок finally может быть просто заменен обычным кодом, который следует за блоками try и catch.
throw – ключевое слово throw используется для реального создания нового исключения, в результате чего выполнение кода попадет в соответствующие блоки catch и finally.
Пример обработки деления на ноль
Если нужный блок catch не найден, то при возникновении исключения программа аварийно завершает свое выполнение. Рассмотрим код:
Чтобы избежать аварийного завершения программы, следует использовать для обработки исключений конструкцию try…catch:
Если произошло исключение, то этот блок try catch обработает исключение, гарантируя тем самым, что приложение не выдаст ошибку необработанного исключения (unhandled exception), ошибки пользователя, и эта ошибка не разрушит процесс выполнения приложения.
Обработка исключений и условные конструкции
Ряд исключительных ситуаций может быть предвиден разработчиком. Например, пусть программа предусматривает ввод числа и вывод его квадрата:
Console.WriteLine(“Введите число”);
int x = Int32.Parse(Console.ReadLine());
x *= x;
Console.WriteLine(“Квадрат числа: ” + x);
Console.Read();
Если пользователь введет не число, а строку, какие-то другие символы, то программа выпадет в ошибку.
С одной стороны, здесь как раз та ситуация, когда можно применить блок try..catch, чтобы обработать возможную ошибку. Однако гораздо оптимальнее было бы проверить допустимость преобразования:
Метод Int32.TryParse() возвращает true, если преобразование можно осуществить, и false – если нельзя.
Фильтры исключений
Фильтры исключений позволяют обрабатывать исключения в зависимости от определенных условий. Для их применения после выражения catch идет выражение when, после которого в скобках указывается условие:
В этом случае обработка исключения в блоке catch производится только в том случае, если условие в выражении when истинно. Например:
В данном случае будет выброшено исключение, так как y=0. Здесь два блока catch, и оба они обрабатывают исключения типа DivideByZeroException, то есть по сути все исключения, генерируемые при делении на ноль.
Но поскольку для первого блока указано условие y == 0 && x == 0, то оно не будет обрабатывать исключение – условие, указанное после оператора when возвращает false.
Поэтому CLR будет дальше искать соответствующие блоки catch далее и для обработки исключения выберет второй блок catch. В итоге если мы уберем второй блок catch, то исключение вообще не будет обрабатываться.
Класс Exception
Базовым для всех типов исключений является тип Exception. Этот тип определяет ряд свойств, с помощью которых можно получить информацию об исключении.
Например, обработаем исключения типа Exception:
Ключевое слово finally
Если нужно определить код, который будет выполняться после выхода из блока try/catch, тогда нужно использовать блок finally. Использование этого блока гарантирует, что некоторый набор операторов будет выполняться всегда, независимо от того, возникло исключение (любого типа) или нет.
Блок finally выполняется и в том случае, если любой код в блоке try или в связанном с ним блоках catch приводит к возврату их метода. Пример:
Генерация исключения и оператор throw
Например, в нашей программе происходит ввод строки, и мы хотим, чтобы, если длина строки будет больше 8 символов, возникало исключение:
Подобным образом можно генерировать исключения в любом месте программы. Но существует также и другая форма использования оператора throw, когда после данного оператора не указывается объект исключения. В подобном виде оператор throw может использоваться только в блоке catch.
Большинство пользователей активно используют антивирусы, чтобы обеспечить безопасность системы, паролей, файлов. Хорошее антивирусное ПО всегда может обеспечить защиту на высоком уровне, вот только многое зависит еще и от действий юзера. Многие приложения дают возможность выбора, что сделать с вредоносной, по их мнению, программой или файлами. Но некоторые не церемонятся и сразу удаляют подозрительные объекты и потенциальные угрозы.
Проблема в том, что каждая защита может сработать впустую, посчитав опасной безвредную программу. Если пользователь уверен в безопасности файла, то ему стоит попытаться поставить его в исключение. Во многих антивирусных программах это делается по-разному.
Добавляем файл в исключения
Чтобы добавить папку в исключения антивируса, нужно немного покопаться в настройках. Также, стоит учитывать, что у каждой защиты свой интерфейс, а это значит, что путь добавления файла может отличатся от других популярных антивирусов.
Kaspersky Anti-Virus
Kaspersky Anti-Virus обеспечивает своим пользователям максимальную безопасность. Конечно, у пользователя могут быть такие файлы или программы, которые считаются данным антивирусом опасными. Но в Kaspersky настроить исключения довольно просто.
Avast Free Antivirus
Avast Free Antivirus имеет яркий дизайн и множество функций, которые могут пригодиться любому юзеру для защиты своих и системных данных. В Avast можно добавлять не только программы, но и ссылки сайтов, которые по вашему мнению безопасны и заблокированы несправедливо.
Avira
360 Total Security
Антивирус 360 Total Security многим отличается от других популярных защит. Гибкий интерфейс, поддержка русского языка и большое количество полезных инструментов доступны вместе с эффективной защитой, которую можно настроить под свой вкус.
Вы выбираете в окне то, что вам нужно и подтверждаете. Так можно поступить и с приложением, которое вы хотите исключить. Просто укажите его папку и она не будет проверяться.
ESET NOD32
ESET NOD32, как и другие антивирусы, имеет функцию добавления папок и ссылок в исключение. Конечно, если сравнивать легкость создания белого списка в других антивирусах, то в НОД32 всё довольно запутанно, но в то же время есть больше возможностей.
Защитник Windows 10
Стандартный для десятой версии антивирус по большинству параметров и функциональных возможностей не уступает решениям от сторонних разработчиков. Как и все рассмотренные выше продукты, он тоже позволяет создавать исключения, причем внести в этот список можно не только файлы и папки, но и процессы, а также конкретные расширения.
Заключение
Теперь вы знаете, как добавить файл, папку или процесс в исключения, вне зависимости от того, какая антивирусная программа используется для защиты компьютера или ноутбука.
Мы рады, что смогли помочь Вам в решении проблемы.
Отблагодарите автора, поделитесь статьей в социальных сетях.
Опишите, что у вас не получилось. Наши специалисты постараются ответить максимально быстро.
Читайте также: