Поиск…


Синтаксис

  • try {...} catch (ошибка) {...}
  • попробуйте {...} наконец {...}
  • try {...} catch (ошибка) {...} finally {...}
  • throw new Error ([сообщение]);
  • throw Error ([сообщение]);

замечания

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

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

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

Взаимодействие с обещаниями

6

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

Promise.resolve(5)
    .then(result => {
        throw new Error("I don't like five");
    })
    .then(result => {
        console.info("Promise resolved: " + result);
    })
    .catch(error => {
        console.error("Promise rejected: " + error);
    });

Promise rejected: Error: I don't like five
7

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

async function main() {
  try {
    await Promise.reject(new Error("Invalid something"));
  } catch (error) {
    console.log("Caught error: " + error);
  }
}
main();

Caught error: Invalid something

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

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

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

try {
   throw new Error('Useful message');
} catch (error) {
   console.log('Something went wrong! ' + error.message);
}

Порядок действий плюс продвинутые мысли

Без блока catch try неопределенные функции будут вызывать ошибки и останавливать выполнение:

undefinedFunction("This will not get executed");
console.log("I will never run because of the uncaught error!");

Выбросит ошибку и не запустит вторую строку:

// Uncaught ReferenceError: undefinedFunction is not defined

Вам нужен блок catch try, похожий на другие языки, чтобы вы могли поймать эту ошибку, чтобы код продолжал выполнять:

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");

Теперь мы поймали ошибку и можем быть уверены, что наш код будет выполнен

// An error occured! ReferenceError: undefinedFunction is not defined(…)
// The code-block has finished
// I will run because we caught the error!

Что делать, если в нашем блоке catch произошла ошибка !?

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    otherUndefinedFunction("Uh oh... ");
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I won't run because of the uncaught error in the catch block!");

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

// The code-block has finished
// Uncaught ReferenceError: otherUndefinedFunction is not defined(…)

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

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    try {
        otherUndefinedFunction("Uh oh... ");
    } catch(error2) {
        console.log("Too much nesting is bad for my heart and soul...");
    }
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");

Уловит все ошибки из предыдущего примера и занесет в журнал следующее:

//Too much nesting is bad for my heart and soul...
//An error occured! ReferenceError: undefinedFunction is not defined(…)
//The code-block has finished
//I will run because we caught the error!

Итак, как мы можем поймать все ошибки !? Для неопределенных переменных и функций: вы не можете.

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

Без защищенного способа вызова ненадежных методов или методов исключения:

function foo(a, b, c) {
    console.log(a, b, c);
    throw new Error("custom error!");
}
try {
    foo(1, 2, 3);
} catch(e) { 
    try {
        foo(4, 5, 6); 
    } catch(e2) {
        console.log("We had to nest because there's currently no other way...");
    }
    console.log(e);
}
// 1 2 3
// 4 5 6
// We had to nest because there's currently no other way...
// Error: custom error!(…)

И с защитой:

function foo(a, b, c) {
    console.log(a, b, c);
    throw new Error("custom error!");
}
function protectedFunction(fn, ...args) {
    try {
        fn.apply(this, args);
    } catch (e) {
        console.log("caught error: " + e.name + " -> " + e.message);
    }
}

protectedFunction(foo, 1, 2, 3);
protectedFunction(foo, 4, 5, 6);

// 1 2 3
// caught error: Error -> custom error!
// 4 5 6
// caught error: Error -> custom error!

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

Типы ошибок

В JavaScript существует шесть конкретных конструкторов ошибок ядра:

  • EvalError - создает экземпляр, представляющий ошибку, возникающую в отношении глобальной функции eval() .

  • InternalError - создает экземпляр, представляющий ошибку, возникающую при возникновении внутренней ошибки в JavaScript-движке. Например, «слишком много рекурсии». (Поддерживается только Mozilla Firefox )

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

  • ReferenceError - создает экземпляр, представляющий ошибку, возникающую при разыменовании недопустимой ссылки.

  • SyntaxError - создает экземпляр, представляющий синтаксическую ошибку, возникающую при анализе кода в eval() .

  • TypeError - создает экземпляр, представляющий ошибку, которая возникает, когда переменная или параметр не имеют допустимого типа.

  • URIError - создает экземпляр, представляющий ошибку, которая возникает, когда encodeURI() или decodeURI() передаются недопустимые параметры.

Если вы внедряете механизм обработки ошибок, вы можете проверить, какой вид ошибки вы вылавливаете из кода.

try {
    throw new TypeError();
}
catch (e){
    if(e instanceof Error){
        console.log('instance of general Error constructor');
    }

    if(e instanceof TypeError) {
        console.log('type error');
    }
}

В таком случае e будет экземпляром TypeError . Все типы ошибок расширяют базовую конструкцию Error , поэтому она также является экземпляром Error .

Помня об этом, мы видим, что проверка e на случай Error в большинстве случаев бесполезна.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow