Более эффективное использование класса ошибок в Node.Js

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

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

function breakPromise() {
    return new Promise((resolve, reject) => {
        reject('something');
    });
}
breakPromise()
    .catch(e => {
        console.log(e);
    });
--------------------------
Result of console.log
something

Рассмотрим приведенный выше фрагмент кода. Мы отклоняем обещание, используя строку. Оператор console.log в блоке catch просто напечатает ‘что-нибудь‘. Представьте, что бы вы сделали, если бы вам поручили исправить ошибку, которая просто выводила такие строки в лог.

плохая-ошибка-3.png

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

function breakPromiseSmart() {
    return new Promise((resolve, reject) => {
        reject(new Error('something bad'));
    });
}

breakPromiseSmart()
    .catch(e => {
        console.log(e);
    });
-----------------------------
Result of console.log
Error: something bad
    at Promise (index.js:3:16)
    at new Promise (<anonymous>)
    at breakPromiseSmart (index.js:2:12)
    at Object.<anonymous> (index.js:7:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)

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

Ошибки, возникающие в node.js, наследуются или являются экземплярами стандартного класса Javascript Error.

Класс ошибок предоставляет некоторые полезные свойства, такие как

  1. сообщение (сообщение об ошибке)
  2. имя (название ошибки)
  3. куча (имя файла, номер строки, стек вызова функции)

Однако мы можем сделать наши журналы ошибок более полезными, добавив свойства к объектам ошибок. лучший способ сделать это — создать собственные классы ошибок, расширив класс Error.

class BadRequestError extends Error {
    constructor(message, meta = {}) {
        super(message);

        Error.captureStackTrace(this, BadRequestError);

        let proto = Object.getPrototypeOf(this);
        proto.name="BadRequestError";

        this.meta = meta;
    }

    toString() {
        return `${super.toString()} ${JSON.stringify(this.meta)}`;
    }
}

function breakPromise() {
    return new Promise((resolve, reject) => {
        reject(new BadRequestError('something bad', {
            expected: 'this',
            got: 'that'
        }));
    });
}

breakPromise()
    .catch(e => {
        console.log(e);
    });
--------------------------------
Result of console.log
{ BadRequestError: something bad
    at Promise (index.js:23:16)
    at new Promise (<anonymous>)
    at breakPromise (index.js:22:12)
    at Object.<anonymous> (index.js:30:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10) meta: { expected: 'this', got: 'that' } }

Мы можем видеть это, расширив класс Error для создания Бадрекуестеррормы смогли добавить гораздо больше информации в трассировку стека и обогатить наши журналы.

Оператор Error.captureStackTrace(this, BadRequestError); Короче говоря, используется для исключения конструктора из трассировки стека.

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

breakPromise()
    .catch(e => {
        if (e instanceof BadRequestError) {
            res.status(400);
        } else if (e instanceof SomeotherError) {
            res.status(412);
        } else {
            res.status(500);
        }
        return res.send({
            message: e.message,
            error: e.meta
        });
    });

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

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

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *