Как избежать вложенных сообщений об ошибках при использовании async / await обнаруженных ошибок? - PullRequest
0 голосов
/ 17 января 2019

Я видел три следующих варианта ошибок выброса:

var response = await api.call()
    .catch((error) => {
        throw error;
    });

var response = await api.call()
    .catch((error) => {
        throw Error(error);
    });

var response = await api.call()
    .catch((error) => {
        throw new Error(error);
    });

Я пробовал throw new Error(error), но цепочка асинхронных функций, передающих ошибку, привела к:

«Ошибка: Ошибка: Ошибка: Фактическое сообщение об ошибке»

Что из этого рекомендуется?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Ни один из них не рекомендуется. Если вы не можете обработать ошибку, не отлавливайте ее. Однако, если вы поймаете некоторые ошибки, вы должны выбросить ошибку как есть , чтобы сохранить всю информацию отладки:

somePromise()
  .catch(reason => {
    if (/* some test about the error */) {
      // handles some errors
    } else {
      throw reason; // <- more on that on @JonasWilms' answer
    }
  })
0 голосов
/ 17 января 2019
 throw Error(error);

, это просто работает, потому что JS всегда выполняет собственные конструкторы как конструкторы, даже если вы вызываете их как функцию. Это похоже на вставку точки с запятой, хотя она работает, я бы не рекомендовал полагаться на нее, потому что это сбивает с толку и может привести к нежелательным побочным эффектам. В принципе, если все работает так, как ожидалось, это так же, как:

 throw new Error(error);

Теперь это также не имеет особого смысла, поскольку вы теряете трассировку стека error s. Когда создается объект ошибки, собирается много информации о том, как произошла ошибка, что действительно полезно для отладки. Поскольку конструктор ошибок ожидает строку в качестве первого аргумента, error преобразуется в строку, в основном это:

 throw new Error(error.toString());

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

 throw error;

просто передает ошибку, которая сохранит всю обязательную информацию.


Для ясности, я лично предпочитаю не смешивать Canables и async / await, поэтому я бы сделал:

try {
  const response = await api.call()
} catch(error) {
    // Some logging, handling, etc.
    throw error;
}

Если вы не можете правильно обработать ошибку и всегда выбросить ее, это бессмысленно, просто не надо try до catch ее. Обрабатывайте его где-нибудь в стеке вызовов, где вы действительно можете его обработать.

...