Меню

Обработка ошибок в JS (error handling)

26.06.2018 - java script, NodeJS, ЯП

Errors in JS

Error Handling Best Practice

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

var myFunc = {};
myFunc();

Для того чтобы красиво оформить возможную ошибку, нужно взять блок, в котором возможна ошибка в try/catch блок. Не забудьте про ключевое слово finaly, которая в этой конструкции будет запускать своё содержимое при любом раскладе.

try {
    var myFunc = {};
    myFunc()
} catch(err) {
    console.log("Oops! Something went wrong");
} finally {
    console.log("Runs everytime...");
}

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

window.onerror = function(message, source, lineNumber, colNumber, errorObject) {
    console.log("Error Details":);
    console.log(`Message: ${message}`);
    console.log(`Source: ${source}`);
    console.log(`Line Number: ${lineNumber}`);
    console.log(`Col Number: ${colNumber}`);
    console.log("Error Object: ", errorObject);
}

Catching Errors from Promises

function getProfile() {
    return new Promise((resolve, reject) => {
        // var myFunc = {};
        // myFunc();
        setTimeout(() => {
            resolve({
                firstName: "John",
                secondName: "Smith",
                age: 43
            });
        }, 3000);
    });
}

getProfile().then(profile => {
    console.log("Profile fetched: ", profile);
    var myFunc = {};
    myFunc();
}, err => {
    console.log("An error has occured: ", err);
}).catch(err => {
    console.log("An error has occured: ". err);
})

Когда мы получаем результат промиса в колбэке, вторым параметром идет возможная ошибка.
Для теста, создадим внутри промиса неверное выражение и запустим… Ошибка обработана и выведена.
Но что если мы переместим неверный код в первый колбэк после промиса. Нода покажет что это необработанная ошибка. Рекомендуется всегда вставлять вконце метод catch. Если промисы составлены в цепочку, всё равно указать catch нужно в самом конце.

Error handling with strategy

Наш обработчик ошибок будет содержать две стратегии — одна для отображения ошибок пользователю, другая для логгирования ошибок.

//app.js
import { ErrorHandler } from "./error-handler";
import { MessageHandlingStrategy } from "./message-handling-strategy";
import { ErrorLoggingStrategy } from "./error-logging-strategy";

const errorHandler = new ErrorHandler(MessageHandlingStrategy, ErrorLoggingStrategy);

window.onerror = function(message, source, lineNumber, colNumber, errorObject) {
    errorHandler.handle("Unknown Error", "Oops! Something went wrong", 5, {
        message, source,lineNumber,colNumber, errorObject
    });
};

//Simulate error
var myFunc={};
myFunc();

//Simulate error
var myFunc={};
myFunc();

//error-handler.js
export class ErrorHandler {
    constructor(messageHandler, logger) {
        if (!messageHandler) {
            throw new Error("Message handler not defined");
        }
        if (!logger) {
            throw new Error("Logger not defined");
        }

        this.messageHandler = messageHandler;
        this.logger = logger;
    }

    handle(header, content, severity, errorObject) {
        this.messageHandler(header, content, severity);
        this.logger(errorObject);
    }
}}
}

//error-logging-strategy.js
export function ErrorLoggingStrategy(error) {
    console.log(`An error occured at file: ${error.source} line ${error.lineNumber} with message ${error.message}`);
}

//message-handling-strategy.js
import * as toastr from 'toastr';

export function MessageHandlingStrategy(header, content, severity) {
    if (severity <= 3) {
        toastr.warning(content, header);
    } else  {
        toastr.error(content, header);
    }
}

//server-logging-stratey.js
const loggingEndpoint = "https://mytestapi/com/v1/loggingg";

export function ServerLoggingStrategy(error) {
    fetch(loggingEndpoint, {
        methos: 'POST',
        body: error
    });
}

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

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