【问题标题】:Google Sheets App Script: Internal error executing the custom functionGoogle 表格应用程序脚本:执行自定义函数时出现内部错误
【发布时间】:2023-02-08 21:27:32
【问题描述】:

我有一个定期返回错误的自定义函数:Internal error executing the custom function. 根据 App Script 网站上的执行页面,自定义函数执行持续时间为 0 (zero) seconds

我已经多次联系谷歌,坚称这是一个平台错误,但我每次都得到相同的答案——“在你的函数中添加一个随机延迟”或“使用指数退避”。我尝试添加一个随机延迟,这确实有点帮助,但错误仍然存​​在 - 只是发生次数减少了。我目前为所有应用程序脚本 API 实现了指数退避,即使使用这种重试逻辑,我也会遇到同样的错误。

我已经遵循了整个 App Script 文档的最佳实践,包括使用范围,即使这样错误仍然存​​在。

还有其他人遇到这个吗?我尝试在我的自定义函数的第一行添加 Logger.log,当我收到此错误时,此代码不会触发。这让我相信自定义函数调用永远不会到达执行代码的服务器。这就是为什么我认为这是一个平台错误。

这是指数退避代码:

function call_(func) {
    for (var n = 0; n < 6; n++) {
        try {
            return func()
        } catch (e) {
            Logger.log(`Retrying... ${n + 1} times exception: ${e}`)
            if (n === 6 - 1) {
                throw e
            }
            Utilities.sleep(
                Math.pow(2, n) * 1000 + Math.round(Math.random() * 1000)
            )
        }
    }
}

这是自定义函数的精简版:

function CUSTOMFUNCTION() {
    let apiResponse = call_(() =>
            UrlFetchApp.fetch(someUrl, {
                muteHttpExceptions: true,
            })
        )

      let response = JSON.parse(call_(() => apiResponse.getContentText()))
    // do some logic with the response
    return value

}

我知道不会捕获 http 异常,这是故意的。在脚本附加的开发表中测试自定义函数时,无论我尝试什么都无法重现错误。该错误仅在通过 Google Cloud Platform (GCP) 部署脚本后才会发生。为清楚起见,在 GCP 内部,我使用 Google Workspace Marketplace SDK 附加脚本 ID,以便任何人都可以使用该插件将其添加到他们的 Google 表格中。

如果有人有任何意见可以帮助解决此错误,我将不胜感激,因为在过去几个月中,谷歌团队在解决此问题方面并没有提供很大帮助。

【问题讨论】:

  • 可以问一下The error only ever happens after the script is deployed via Cloud Platform.的详细情况吗?
  • 函数外是否有全局变量或任何加载代码?
  • @Tanaike 我更新了问题以更好地解释为什么我使用 GCP
  • @TheMaster 我在脚本中确实有全局变量和全局函数,例如上面显示的 call_ 函数。全局变量会导致什么问题?
  • 除了函数之外,是否有任何立即执行的全局代码?它们在调用自定义函数之前加载,因此可能对此类未知错误负责。

标签: google-apps-script google-sheets internal-server-error custom-function


【解决方案1】:

API 限制。 https://developers.google.com/sheets/api/limits

实施指数退避,为我们解决了这个问题。

async function myFunction(params) {
  let result = -1

  for (let i = 0; i<10; i++){
    try {
      let response = await UrlFetchApp.fetch("MY URL");
      result = await response.getContentText()
      if (result >= 0) {return result}
    } catch(err) {
      await setTimeout(r, 1000*i);
    }
  }
  return err.message
}

然后我们也将工作表设置为自动刷新公式
https://spreadsheetpoint.com/auto-refresh-google-sheets/ (可能没有关系)

【讨论】:

  • 感谢您的回答。这或多或少是我们已经拥有的 - 我最终弄清楚了这个问题,这是由于其他原因,我将很快回答这个问题。
【解决方案2】:

这个问题最终是由我们的整体脚本大小引起的。

在与谷歌联系后,我们获悉,对于每个自定义功能请求,谷歌将检索您的 App 脚本代码的全部内容。不仅仅是用于自定义功能的代码/文件。它们的下载大小上限为 5mb。

因此,我们更改了 webpack 配置,从而使捆绑包的大小小得多 (<1mb)。谷歌还创建了一个文件缓存来加速大型 App Script 项目的这个过程。

希望这会帮助遇到此问题的其他人。

【讨论】:

    最近更新 更多