Разорвать цепь обещаний с брошенным исключением - PullRequest
0 голосов
/ 31 октября 2018

В настоящее время, если в обратном вызове asyncFunction1() s обнаружена ошибка, приложение корректно сгенерирует исключение «Проблема A». Однако это проходит через цепочку обещаний, и приложение в конечном итоге увидит «Проблема B», что означает, что приложение показывает неправильную ошибку пользователю.

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

Информация о классе HttpsError находится здесь: https://firebase.google.com/docs/reference/functions/functions.https.HttpsError

В нем прямо упоминается:

Убедитесь, что вы выбросили это исключение на верхний уровень вашей функции. а не из-за обратного вызова, так как это не обязательно завершится функция с этим исключением.

Кажется, я попал в эту ловушку, но не знаю, как ее обойти. Если бы кто-то мог помочь мне реорганизовать код, чтобы я мог эффективно отлавливать и обрабатывать эти ошибки должным образом, это было бы очень полезно.

exports.charge = functions.https.onCall(data => {
  asyncFunction1()
    .then(() => {
      asyncFunction2();
    })
    .catch((err) => {
      throw new functions.https.HttpsError(
        'not-found',
        'Problem A'
      );
    })
    .then(() => {
      asyncFunction3();
    })
    .catch((err) => {
      throw new functions.https.HttpsError(
        'not-found',
        'Problem B'
      );
    })
});

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Хотелось бы что-нибудь подобное?

exports.charge = functions.https.onCall(data => {
   return Promise.resolve().then(
      () => {
          return asyncFunction1();
      }).then(
      () => {
          return asyncFunction2();
      }).then(
      () => {
          return asyncFunction3();
      }).catch(
      err => {
          throw new functions.https.HttpsError(err);
      });
}
0 голосов
/ 31 октября 2018

Есть несколько способов подойти к этому:

  1. Вы можете сделать так, чтобы каждая асинхронная функция просто устанавливала соответствующую ошибку, когда она отклоняется, поэтому вам не нужно вручную добавлять нужную ошибку в вашу собственную .catch().

  2. Вы можете проверить в последнем .catch(), чтобы увидеть, была ли уже установлена ​​соответствующая ошибка, и просто сбросить ее, если это так, вместо того, чтобы переопределить ее с другой ошибкой.

  3. Вы можете поставить последний .catch() на вызов asyncFunction3() напрямую, а не на всю цепочку, как это, так что вы нацелены только на отказ от этой функции с этим кодом ошибки:

Модифицированный код:

exports.charge = functions.https.onCall(data => {
    return asyncFunction1().then(() => {
        return asyncFunction2();
    }).catch((err) => {
        // set appropriate error for rejection in either of the first two async functions
        throw new functions.https.HttpsError('not-found', 'Problem A');
    }).then(() => {
        return asyncFunction3().catch((err) => {
            // set appropriate error for rejection in asyncFunction3
            throw new functions.https.HttpsError('not-found', 'Problem B');
        });
    });      
});

Примечание: я также добавил несколько операторов return, чтобы убедиться, что обещания связаны в цепочку и возвращаются из экспортированной функции. И я сжал логику, чтобы было легче читать.


Это может также относиться к асинхронному / ожидающему (хотя я не совсем уверен, позволяет ли functions.https.onCall() это или нет):

exports.charge = functions.https.onCall(async (data) => {
    try {
        await asyncFunction1()
        await asyncFunction2();
    } catch(e) {
        throw new functions.https.HttpsError('not-found', 'Problem A');
    }
    try {
        await asyncFunction3();
    } catch(e) {
        throw new functions.https.HttpsError('not-found', 'Problem B');
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...