Обработка ошибок Promise Chaining

1

Я изучаю, как использовать Promise без библиотек. Из того, что я прочитал, я мог объединить Promise вместе, а затем добавить .catch в конце для обработки ошибок.

Что я ожидаю

Поэтому, если я изменю URL-адрес на какой-то неверный URL-адрес, не должен ли я улавливать ошибку и останавливать выполнение всей программы?

Что я вижу сейчас?

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

const request = require("request");

new Promise((resolve, reject) => {
  request(
    "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis",
    (err, res, body) => {
      if (err) {
        reject("bad call on geo code!");
      }
      resolve(JSON.parse(body).results[0].geometry.location);
    }
  );
})
  .then(res => {
    const {lat, lng} = res;
    return new Promise((resolve, reject) => {
      request(
        'https://api.darksky.net/forecast/6fb416a8313aabd902a22558e07cc032/${lat},${lng}',
        (err, res, body) => {
          if (err) {
            reject("bad call on darksky");
          }
          resolve(JSON.parse(body));
        }
      );
    });
  })
  .then(res => {
    const currentTemp = res.currently.temperature;
    const feelTemp = res.currently.apparentTemperature;
    const temps = {currentTemp, feelTemp};
    return new Promise((resolve, reject) => {
      request(
        "http://ron-swanson-quotes.herokuapp.com/v2/quotes",
        (err, res, body) => {
          if (err) {
            reject("bad call on quotes");
          }
          resolve({temps, body});
        }
      );
    });
  })
  .then(res => {
    console.log(
      'Today weather is ${res.temps.currentTemp}, and it feels like ${res
        .temps
        .feelTemp}! \nAnd here is your stupid quote of the day: \n${JSON.parse(
        res.body
      )[0]}'
    );
  })
  .catch(err => {
    console.log(err);
  });

Сообщение об ошибке:

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

SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at Promise.then.then.then.res (/Users/leoqiu/reacto/playground/6_promiseMethod.js:48:74)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
  • 0
    В чем ошибка?
  • 0
    это зависит от того, на каком этапе я изменяю URL, поэтому в основном отклоняю, выбрасываю ошибку, и сообщение об ошибке передается вниз, которое обрабатывается res для следующего обещания. Таким образом, ошибка - просто ошибка анализа JSON.
Показать ещё 9 комментариев
Теги:
promise

2 ответа

0
Лучший ответ

Когда вы вызываете reject() внутри вашего оператора if, вы не возвращаетесь, и вы не используете else чтобы ваше resolve(JSON.parse(body).results[0].geometry.location); все еще выполняется, и это создает исключение.

Вы можете изменить это:

new Promise((resolve, reject) => {
  request(
    "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis",
    (err, res, body) => {
      if (err) {
        reject("bad call on geo code!");
        return;
      }
      resolve(JSON.parse(body).results[0].geometry.location);
    }
  );
})

Это распространенная ошибка, которую люди думают, что reject() работает как break или какой-то другой оператор потока управления, потому что reject() - это тип потока управления обещаниями. Но это не останавливает выполнение в вашем блоке, поэтому вам нужно либо return после него, либо использовать else.

Или я предпочитаю использовать if/else потому что я думаю, что это делает логику еще более очевидной:

new Promise((resolve, reject) => {
  request(
    "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis",
    (err, res, body) => {
      if (err) {
        reject("bad call on geo code!");
      } else {
        resolve(JSON.parse(body).results[0].geometry.location);
      }
    }
  );
})
  • 0
    благодарю вас! Это решило это!
0

Основываясь на предложении Патрика Эванса...

reject не останавливает выполнение программы, поэтому сообщение об ошибке переходит к следующему обещанию, поэтому возникает ошибка json parsing.

Решение просто return результат отклонения.

if (err) {
    reject("bad call on geo code!");
    return err;
  }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню