@gugozoha

Почему promise.catch() не перехватывает ошибку?

Код без ошибки (работает нормально):
let userInsert = new Promise((resolve, reject) => {
            db.query('INSERT INTO users (email, password) VALUES (?, ?)', [user.email, user.password])
        });

        userInsert
            .catch(function (err) {
                console.log('error');
            });


Код с ошибкой запроса (крашит программу, хотя должен перехватываться в catch):
let userInsert = new Promise((resolve, reject) => {
            db.query('INSERT INTO users (email, passwordError) VALUES (?, ?)', [user.email, user.password])
        });

        userInsert
            .catch(function (err) {
                console.log('error');
            });


Проверяем, перехватывает ли промис шибки. Работает нормально.
let p = new Promise((resolve, reject) => {
      // то же что reject(new Error("o_O"))
      throw new Error("o_O");
    })
    
    p.catch(alert('error'));


Собственно, почему второй код не перехватывает ошибку? А выводит в консоль:
Error: ER_BAD_FIELD_ERROR: Unknown column 'passwordError' in 'field list'
  • Вопрос задан
  • 1412 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Вы ничего не резолвите и не режектите, следовательно данный промис никогда не пойдет дальше по цепочке.
Очевидно, что db.query асинхронная, но так как она не получила колбэка, то выкидывает свое исключение в общий поток, к этому моменту функция-обработчик промиса уже успешно завершена, естественно она не ловит при этом ошибку.
Многое конечно зависит от драйвера БД, но подозреваю что нужно сделать так:
let userInsert = new Promise((resolve, reject) => {
  db.query('INSERT INTO users (email, password) VALUES (?, ?)', [user.email, user.password], err => {
    if(err) {
      reject(err);
      return;
    }
    resolve();
  });
});
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
@fetis26
Ну, за фронтенд!
ну может он внутри себя ловит ошибку и выводит ее в консоль. а промис реджектит, например
Ответ написан
Комментировать
Promise.catch это не часть try/catch стейтмента. promise.catch это просто шорткат для promise.then(null, function() {})со всеми вытекающими.
Ответ написан
Комментировать
@Faliah
Желательно указать каким драйвером, для какой БД вы пользуетесь. Мне странно видеть в коде на node.js блокирующий запрос к БД, когда почти для любых i/o операций используются неблокирующие вызовы с коллбэками. Вполне возможно, что вам нужно вручную выбросить исколючение в коллбэке/зареджектить промис при наличии err, в вызове коллбэка после запроса
Ответ написан
Комментировать
Lynn
@Lynn
nginx, js, css
Он может перехватить только синхронные исключения.
Простой пример:
let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        throw 'WTF';
    }, 0);
});

p.catch( console.log );


Ну и вообще, очень странно видеть создание промиса в котором не вызываются ни resolve, ни reject.

Правильно должно быть примерно так:
let userInsert = new Promise((resolve, reject) => {
  db.query(
    'INSERT INTO users (email, password) VALUES (?, ?)',
    [user.email, user.password],
    (err, result) => {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    }
  )
});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы