【问题标题】:Does throwing an HttpsError() in a Firebase Callable Function cause the instance to be thrown away (and therefore cause a cold-start)?在 Firebase 可调用函数中抛出 HttpsError() 是否会导致实例被丢弃(并因此导致冷启动)?
【发布时间】:2021-08-14 14:51:57
【问题描述】:

在 Google Cloud Functions documentation about error reporting 中,它说“......某些类型的未捕获异常(例如异步抛出的异常)将导致在未来的函数调用时发生冷启动。这会增加您的函数将跑起来。”

而在Firebase Documentation about handling errors 中,它说我们应该“通过抛出(或返回被拒绝的 Promise)函数实例来从可调用返回错误。https.HttpsError ...以确保客户端获得有用的错误详细信息”:

if (!(typeof text === 'string') || text.length === 0) {
  // Throwing an HttpsError so that the client gets the error details.
  throw new functions.https.HttpsError('invalid-argument', 'The function must be called with one arguments "text" containing the message text to add.');
}

所以在我看来,与其他抛出的 Errors 相比,这听起来像是 HttpsError 受到了某种特殊对待。

我的问题是:如上所示在可调用云函数中抛出HttpsError 会导致函数失败,从而导致冷启动 用于后续调用?

如果是这样的话,抛出 HttpsErrors 将没有意义,因为在这些情况下,像缺少参数这样的“预期”错误,出于性能原因,函数实例可以而且确实应该被重用。

所以如果是这样的话,最好只返回如下内容:

return {
  error: true,
  error_code: 'invalid_argument',
}

并在客户端而不是 HttpsError 上处理此问题。

或者向客户端返回错误而不导致函数导致冷启动的正确解决方案是返回被拒绝的Promise而不是抛出?

if (!(typeof text === 'string') || text.length === 0) {
  // Throwing an HttpsError so that the client gets the error details.
  return Promise.reject(new functions.https.HttpsError('invalid-argument', 'The function must be called with one arguments "text" containing the message text to add.'));
}

根据文档,throw new HttpsError(...)return Promise.reject(new HttpsError(...)) 之间似乎没有区别,但也许我读错了。

【问题讨论】:

    标签: javascript typescript firebase google-cloud-functions


    【解决方案1】:

    使用 Firebase Callable Cloud Functions,sending back a resultthrowing an instance of functions.https.HttpsError 实际上向 Cloud Function 平台表明您的函数已达到其终止条件或状态,并且平台可以关闭运行您的函数的 Cloud Function 实例。

    需要注意的是,我们使用can:平台可能会立即关闭实例,也可能不会,让它闲置一段时间。这是你无法控制的。

    结果:如果在实例仍在运行时发生下一次调用您的 Cloud Function相同的 Cloud Function 处于空闲状态且仍处于运行状态)。相反,如果在下一次调用发生时实例被关闭(并且没有相同 Cloud Function 的其他实例空闲且启动),则平台将启动一个新实例并进行冷启动。

    换句话说,Cloud Function 平台将“查看”是否有此特定 Function 的实例处于运行状态并且空闲。如果是,它将使用它,如果不是,它将启动一个新实例。

    结论,在您的情况下,关于如何返回诸如“缺少参数”之类的错误:您可以像在问题中那样返回一个对象(或返回一个使用该对象解析的 Promise如果函数实现了一些异步操作)或抛出functions.https.HttpsError 的实例。在冷启动方面不会有任何区别,请参阅下面@samthecodingman 的评论。


    请注意以下关于此anwser的第一句话:

    “发回结果”的意思是:

    • 如果您的 Cloud Function 中没有异步操作,则返回一个 JavaScript 对象(有关加法操作的结果,请参见 doc 中的示例),或者;
    • 在异步操作后返回一个 Promise。

    “抛出functions.https.HttpsError的实例”的意思是:

    • 在做throw new functions.https.HttpsError(...),或者;
    • 返回一个被 functions.https.HttpsError 实例拒绝的 Promise。

    【讨论】:

    • 可能值得一提的是,可调用函数处理程序中引发的错误包含在 Promise 链中,这也是它们不会终止实例的原因(与传统 HTTPS 请求处理程序中引发的错误相反,后者只是快递处理程序)
    • 感谢您的详细回答,但我仍然不能 100% 确定您回答的一个核心方面。我知道功能可以随时保持空闲或关闭的一般行为。只考虑 函数将保持空闲 状态:cloud.google.com/functions/docs/bestpractices/… 说“在使用异常处理的语言中,不要抛出未捕获的异常,因为它们会在未来的调用中强制冷启动。”。所以可以肯定的是:throw new HttpsError(...)return Promise.reject(new HttpsError(...)) 都不算作未捕获的异常?
    • 您好@sceee,请参阅来自 samthecodingman 的评论
    猜你喜欢
    • 2022-01-08
    • 2018-09-21
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多