vue-resource: поймать Uncaught (в обещании) при перехвате ошибки ajax

Я использую vue-resource для получения данных с сервера. Пользователю необходимо иметь токен JWT, чтобы получить правильные данные. Если токен недействителен или просрочен, возвращается статус 401. Если пользователь пытается получить доступ к запрещенной странице, возвращается ошибка 403.

Я хотел бы поймать эти ошибки и обработать их соответствующим образом (глобально). Это означает, что вызовы должны полностью обрабатываться перехватчиком (если 401, 403).

Как я могу предотвратить сообщение браузера «Uncaught (in promise)» и создать некоторую глобальную обработку ошибок? Я не хочу иметь локальный обработчик ошибок при каждом вызове.

У меня есть следующий перехватчик:

Vue.http.interceptors.push(function (request, next) {
    request.headers.set('Authorization', Auth.getAuthHeader());

    next(function (response) {
        if (response.status === 401 || response.status === 403) {
            console.log('You are not logged in or do not have the rights to access this site.');
        }
    });
});

И следующий вызов в Vue methods:

methods: {
    user: function () {
        this.$http.get('http://localhost:8080/auth/user').then(function (response) {
            console.log(response);
        });
    }
}

person ssc-hrep3    schedule 05.04.2017    source источник
comment
Похоже, вы уже обрабатываете ответы об ошибках в своем перехватчике. Вы не хотите скрывать неудачные ответы / обещания от вызывающих абонентов, иначе все будет выглядеть правильно. Я бы не стал беспокоиться об ошибках консоли, большинство пользователей их не увидит   -  person Phil    schedule 06.04.2017
comment
@Фил, спасибо за ответ. Нет ли побочного эффекта, когда исключение не перехватывается в then()? Обычно я стараюсь предотвратить ошибки браузера (кроме ошибок HTTP).   -  person ssc-hrep3    schedule 08.04.2017


Ответы (1)


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

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

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

Но это приводит к ситуации, когда появляется ошибка Uncaught (in promise), потому что браузер будет думать, что вы не обработали ошибку, тогда как на самом деле вы это сделали в своем глобальном обработчике ошибок.

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

Итак, что мы часто делаем, так это имеем свои собственные классы ошибок, и когда возникает ошибка ответа, мы преобразуем ошибку в один из наших классов ошибок, в зависимости от кода состояния HTTP.

Мы также добавляем свойство к этой ошибке, что-то вроде ignoreUnhandledRejection, и устанавливаем для него значение true. Затем вы можете использовать глобальный обработчик, чтобы отфильтровать эти ошибки и игнорировать их, потому что вы знаете, что вы уже обработали их глобально:

/**
 * Prevent logging already processed unhandled rejection in console
 */
window.addEventListener('unhandledrejection', event => {
  if (event.reason && event.reason.ignoreUnhandledRejection) {
    event.preventDefault();
  }
});
person Adam Reis    schedule 07.05.2019