JavaScript try/catch: ошибки или исключения?

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

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

catch(err) {
DFTools.console.log("someMethod caught an error: ",err.message);
...

или

catch(ex) {
DFTools.console.log("someMethod caught an exception: ",ex.message);
...

Очевидно, что код функционирует должным образом в любом случае, но он начинает беспокоить меня, что я иногда упоминаю "ошибки", а иногда и "исключения". Как я уже сказал, может быть, я раскалываю волосы, но что такое правильная терминология? "Исключение" или "Ошибка"?

Ответ 1

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

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

Ответ 2

спецификация ECMAScript называет их исключениями. Возможно, вы захотите сделать то же самое.

Чтобы сделать ваш журнал более информативным:

catch(ex) {
    DFTools.console.log("someMethod caught an exception of type " 
       + ex.name + ": ", ex.message);

Вы также можете иметь в виду, что исключения (к сожалению) могут быть любого типа и поэтому не обязательно иметь свойства name и message:

catch(ex) {
    if (ex.message && ex.name) {        
        DFTools.console.log("someMethod caught an exception of type " 
           + ex.name + ": ", ex.message);
    } else /* deal with it somehow */

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

function logExceptions(methodName, action) {

    try {

        action();

    } catch (ex) {
        if (ex.message && ex.name) {        
            DFTools.console.log("someMethod caught an exception of type " 
               + ex.name + ": ", ex.message);
        } else {
            DFTools.console.log("someMethod caught a poorly-typed exception: " + ex);
        }
    }
}

Теперь вы можете сказать:

logExceptions(function() {

    // do some risky stuff...

});

Ответ 3

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

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

Ответ 4

В JavaScript это называется Error Catching. Поэтому я предлагаю вам использовать ошибку вместо исключения. Оставьте выбор в середине с помощью "e". Как в примерах Mozilla. Справочник по Mozilla Core JavaScript 1.5

Ответ 5

ОСНОВНОЕ ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не считаю, что есть "правильный" ответ на этот вопрос. Представленные здесь мнения являются субъективными и личными. Более того, идеи, которые я собираюсь поддержать, полезны только в том случае, если вы собираетесь делать разные вещи с помощью разных, глагольных, недостатков... поскольку вы можете использовать систему в соответствии с информативным ответом Даниэля Эрвикера. Имея это в виду:

Я утверждаю, что "EXCEPTION является исключительным". ОШИБКА менее неожиданна.

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

Примечание: в этом мысленном эксперименте GetFile возвращает UNDEFINED, если он не может найти указанный файл.

function AlwaysGetFile(name){
    var file = null;
    if(FileExists(name)){
        file = GetFile(name);
        if(typeof file === "undefined"){
            throw new "couldn't retrieve file" EXCEPTION
        }
    }
    else{
        throw new "file does not exist" ERROR
    }
    return file;
}

В случае, когда потребитель вызывает GetFileOrThrow с именем файла, которое не существует, произойдет ERROR. На мой взгляд, различие заключается в том, что код более высокого уровня (или пользовательский ввод) делает что-то неправильно... эта функция должна передать ERROR вверх по линии этому высокоуровневому коду, который может решить, что делать с этим результатом. Считайте это так: эта функция будет говорить любым потребляющим функциям:

Посмотрите, мой друг, я знаю, что происходит здесь: это ERROR, чтобы запросить BobAccounts.xml, так что не делайте этого снова! О, и если вы думаете, что теперь знаете, что могло пойти не так (злоупотребляя мной), продолжайте и попытайтесь оправиться от него!

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

О, любимые! Извините, я смиренно прошу прощения, но что-то ИСКЛЮЧИТЕЛЬНОЕ, что я действительно не понимаю, пошло не так. Я не думаю, что ваш запрос на BobAccounts.xml был необоснованно... и я знаю, что я должен выполнить его для вас. Поскольку я более низкий уровень кода, чем вы, я действительно должен знать, что происходит... но я не... и поскольку у вас меньше шансов, чем я понимаю эту ИСКЛЮЧИТЕЛЬНУЮ ситуацию, я думаю, вы, вероятно, лучше всего прекратите то, что вы делаете, и пусть это сообщение дойдет до вершины... Я имею в виду, что здесь происходит что-то серьезное.

Итак, я полагаю, что мое резюме таково: если ошибка произошла в коде более высокого порядка (вы получили плохие данные), бросьте ОШИБКУ. Если ошибка произошла в коде нижнего порядка (функция, от которой вы зависели не удалось, каким вы не поняли и не могли планировать) выбросить EXCEPTION... и если ошибка произошла в функции, которую вы сейчас пишете. ну, если вы знаете об этом, тогда исправьте это!

И, наконец, более непосредственный ответ на исходный вопрос: с точки зрения обработки ОШИБКИ и ИСКЛЮЧЕНИЙ, мой совет будет: обрабатывать все ОШИБКИ изящно (необязательно записывая их в журнал)... но эффективно обрабатывайте ИСКЛЮЧЕНИЯ; только попытайтесь восстановиться из ИСКЛЮЧЕНИЯ, если вы действительно уверены, что знаете, что это такое и почему это произошло, иначе пусть оно пузырится (перетаскивая его, если вам нужно).

Ответ 6

То, что вы получаете в блоке Catch, является Исключением, поэтому я называю это как исключение...

Если это ошибка - я могу обработать ее в своем коде, и я обычно не ожидаю увидеть ее в блоке Catch

НТН.