在另一个承诺的回调中捕获承诺错误

时间:2018-11-03 12:44:16

标签: javascript node.js firebase promise google-cloud-functions

下面的代码按预期运行。如果调用了charge函数,则该函数从firestore获取相关的票证对象,然后将其返回给客户端。

如果票证不存在,该函数将抛出一个带有错误消息的HttpsError,该错误消息将由客户端进行解析。

exports.charge = functions.https.onCall(data => {
  return admin.firestore().collection('tickets').doc(data.ticketId.toString()).get()
    .then((snapshot) => {
      return { ticket: snapshot.data() }
    })
    .catch((err) => {
      throw new functions.https.HttpsError(
        'not-found', // code
        'The ticket wasn\'t found in the database'
      );
    });
  });

此后出现问题。现在,我需要使用Stripe向用户收费,Stripe是另一个异步过程,它将返回Promise。收费需要通过第一种异步方法获得的定价信息,因此需要在检索snapshot之后调用。

exports.charge = functions.https.onCall(data => {
  return admin.firestore().collection('tickets').doc(data.ticketId.toString()).get()
    .then((snapshot) => {
      return stripe.charges.create(charge) // have removed this variable as irrelevant for question
        .then(() => {
          return { success: true };
        })
        .catch(() => {
          throw new functions.https.HttpsError(
            'aborted', // code
            'The charge failed'
          );
        })
    })
    .catch(() => {
      throw new functions.https.HttpsError(
        'not-found', // code
        'The ticket wasn\'t found in the database'
      );
    });
  });

我的问题是在新的charge请求中捕获错误。看来,如果收费失败,它会成功调用第一个“中止的”渔获物,然后将其传递给父渔获物,并且该错误将被覆盖,并且应用程序会看到“未找到机票”错误。

如何阻止这种情况的发生?我需要分别捕获这两个错误,并为每个错误抛出一个HttpsError

2 个答案:

答案 0 :(得分:1)

通常,可以通过添加public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder) { $request = Request::createFromGlobals(); /** @var User $user */ $user = $this->getUser(); $user->setName($request->request->get('name')); $user->setEmail($request->request->get('email')); $errors = $validator->validate($user); if (count($errors) == 0) { $entityManager = $this->getDoctrine()->getManager(); $entityManager->persist($user); $entityManager->flush(); return new JsonResponse(['success' => true]); } $data = []; foreach ($errors as $error) { $data[$error->getPropertyPath()] = $error->getMessage(); }; return new JsonResponse(['success' => false, 'errors' => $data], 400); } 节点然后与最后一个status块链接来解决此类问题。您可以尝试以下操作

then

答案 1 :(得分:0)

不要将then嵌套在另一个then内进行多项工作:

work1
.then((work1_results) => {
    return work2.then((work2_results) => {
        // this is bad
    })
})

相反,请按链接序列执行所有工作:

work1
.then((work1_results) => {
    return work2
})
.then((work2_results) => {
    // handle the results of work2 here
})

如果需要在回调之间累积数据,则可以将中间结果存储在范围更广的变量中。