问题排查

即使是经验最丰富的开发者,也很少能一次性正确编写代码,因此问题排查是开发过程中的重要环节。在本部分中,我们将介绍一些有助于您查找、了解和调试脚本中的错误的技术。

错误消息

当脚本遇到错误时,系统会显示一条错误消息。该消息随附了一个用于问题排查的行号。以这种方式显示的基本错误类型有两种:语法错误运行时错误

语法错误

语法错误是由于编写的代码不符合 JavaScript 语法而造成的,当您尝试保存脚本时,系统会立即检测到这些错误。 例如,以下代码段包含语法错误:

function emailDataRow(rowNumber) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var rowData = data[rowNumber-1].join(" ";
  MailApp.sendEmail('john@example.com',
                    'Data in row ' + rowNumber,
                    rowData);
}

此处的语法问题是第四行末尾缺少 ) 字符。当您尝试保存脚本时,会收到以下错误:

实参列表后缺少“)”。(第 4 行)

这些类型的错误通常很容易排查,因为它们会立即被发现,并且通常有简单的原因。您无法保存包含语法错误的文件,这意味着只有有效的代码才能保存到您的项目中。

运行时错误

这些错误是由函数或类的使用不当引起的,只有在脚本运行后才能检测到。例如,以下代码会导致运行时错误:

function emailDataRow(rowNumber) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var rowData = data[rowNumber-1].join(" ");
  MailApp.sendEmail('john',
                    'Data in row ' + rowNumber,
                    rowData);
}

代码格式正确,但在调用 MailApp.sendEmail 时,我们传递的是电子邮件地址的值“john”。由于这不是有效的电子邮件地址,因此运行脚本时会抛出以下错误:

电子邮件无效:john(第 5 行)

这些错误之所以更难排查,是因为您传递给函数的数据通常不是在代码中写入的,而是从电子表格、表单或其他外部数据源中提取的。使用以下调试技术有助于您找出这些错误的原因。

常见错误

下面列出了常见错误及其原因。

服务调用次数过多:<操作名称>

此错误表示您已超出特定操作的每日配额。 例如,如果您在一天内发送的电子邮件过多,就可能会遇到此错误。对于消费者账号、网域账号和高级账号,配额设置在不同级别,并且 Google 可能会随时更改这些配额,恕不另行通知。您可以在 Apps 脚本配额文档中查看各种操作的配额限制。

服务器不可用。服务器出错,请重试。

这些错误可能有以下几种原因:

  • Google 服务器或系统暂时不可用。请稍等片刻,然后尝试再次运行脚本。
  • 您的脚本中存在没有相应错误消息的错误。尝试调试脚本,看看能否找出问题。
  • Google Apps 脚本中存在一个导致此错误的 bug。如需有关如何搜索和提交 bug 报告的说明,请参阅问题。在提交新 bug 之前,请先搜索一下,看看是否已有人报告过该 bug。

需要授权才能执行该操作。

此错误表示脚本缺少运行所需的授权。 当脚本在脚本编辑器中或通过自定义菜单项运行时,系统会向用户显示授权对话框。不过,当脚本通过触发器从嵌入 Google 协作平台的网页运行,或作为服务运行时,系统无法显示对话框,并会显示此错误。

如需授权脚本,请打开脚本编辑器并运行任意函数。系统会显示授权提示,以便您授权脚本项目。如果脚本包含新的未经授权的服务,您必须重新授权该脚本。

此错误通常是由以下原因造成的:触发器在用户授权之前触发,或者触发器的授权已过期。如果您无法访问脚本项目(例如,因为错误发生在您使用的插件中),通常可以再次使用该插件来授权脚本。如果某个触发器持续触发并导致此错误,您可以按以下步骤移除触发器:

  1. 在 Apps 脚本项目的左侧,点击触发器图标
  2. 在要移除的触发器右侧,依次点击“更多”图标 >“删除触发器”

您还可以通过卸载插件来移除有问题的插件触发器。

精细权限也可能会导致这些错误。除非执行是由触发器调用的,否则 Apps 脚本会自动向用户请求缺少的权限。请参阅我们的授权范围页面,以防止触发器执行出现此错误。

访问遭拒:DriveApp网域政策已停用第三方云端硬盘应用

Google Workspace 网域的管理员可以为其网域停用 Drive API,从而阻止其用户安装和使用 Google 云端硬盘应用。此设置还会阻止用户使用采用 Drive 服务高级 Drive 服务的 Apps 脚本插件(即使在管理员停用 Drive API 之前,该脚本已获得授权)。

不过,如果使用云端硬盘服务的插件或 Web 应用已发布以供网域范围内的安装,并且管理员已为网域中的部分或所有用户安装该插件或 Web 应用,那么即使云端硬盘 API 在网域中处于停用状态,这些用户的脚本函数也能正常运行。

脚本无权获取活跃用户的身份。

表示脚本无法获取有效用户的身份和电子邮件地址。此警告是由对 Session.getActiveUser() 的调用导致的。 如果脚本以 AuthMode.FULL 以外的授权模式运行,调用 Session.getEffectiveUser() 也可能会导致此错误。 如果发出此警告,则后续对 User.getEmail() 的调用只会返回“”。

您可以根据脚本的运行授权模式,通过多种方式来排查此警告。授权模式在触发型函数中作为 e event 参数authMode 属性公开。

缺少库

如果您向脚本添加热门,即使该库已列为脚本的依赖项,您也可能会收到一条错误消息,指出该库缺失。原因可能是同时访问该库的人数过多。为避免此错误,请尝试以下解决方案之一:

  • 将库的代码复制并粘贴到脚本中,然后移除库依赖项。
  • 复制库脚本,然后以库的形式从您的账号中部署该脚本。请务必将原始脚本中的依赖项更新为新库,而不是公开库。

缺少库版本或部署版本,导致发生错误。错误代码 Not_Found

此错误消息表示存在以下某种情况:

  • 已删除脚本的已部署版本。如需更新已部署的脚本版本,请参阅修改版本化部署
  • 脚本使用的库的版本已被删除。如需查看缺少哪个库,请依次点击库名称旁边的 更多 > 在新标签页中打开。如果缺少库,系统会显示错误消息。找到需要更新的库后,请执行以下任一操作:
    • 更新库以使用其他版本。请参阅更新库
    • 从脚本项目和代码中移除已删除的库。请参阅移除媒体库
  • 您的脚本所使用的库的脚本包含另一个使用已删除版本的库。执行以下一项操作:
    • 如果您对脚本使用的库具有修改权限,请将该脚本中的辅助库更新为现有版本。
    • 更新库以使用其他版本。请参阅更新库
    • 从脚本项目和代码中移除库。请参阅移除媒体库

使用高级服务调用 Google Chat API 时,出现“错误 400:invalid_scope”

如果您遇到 Error 400: invalid_scope 错误,并显示 Some requested scopes cannot be shown 错误消息,则表示您未在 Apps 脚本项目的 appsscript.json 文件中指定任何授权范围。在大多数情况下,Apps 脚本会自动确定脚本所需的范围,但当您使用 Chat 高级服务时,必须手动将脚本使用的授权范围添加到 Apps 脚本项目的清单文件中。请参阅设置明确的范围

如需解决此错误,请将相应的授权范围添加到 Apps 脚本项目的 appsscript.json 文件中,作为 oauthScopes 数组的一部分。例如,如需调用 spaces.messages.create 方法,请添加以下内容:

"oauthScopes": [
  "https://www.googleapis.com/auth/chat.messages.create"
]

您的管理员不允许通过 UrlFetch 调用 <网址>

Google Workspace 管理员可以在管理控制台中启用许可名单,以控制您可以通过 Google Apps 脚本访问哪些外部网域。

如需解决此错误,请与您的管理员联系,让他们将相应网址添加到许可名单中。

调试

并非所有错误都会导致系统显示错误消息。可能存在一种更细微的错误,即代码在技术上是正确的并且可以执行,但结果与您的预期不符。以下是一些策略,可帮助您处理此类情况并进一步调查未按预期运行的脚本。

日志记录

在调试时,记录脚本项目执行过程中的信息通常很有帮助。Google Apps 脚本提供了两种记录信息的方法:Cloud Logging 服务和内置于 Apps 脚本编辑器的更基本的 Logger 和 console 服务

如需了解详情,请参阅日志记录指南

Error Reporting

因运行时错误而发生的异常会自动使用 Google Cloud Error Reporting 服务记录。借助此服务,您可以搜索和过滤脚本项目创建的异常消息。

如需访问 Error Reporting,请参阅在 Google Cloud Platform 控制台中查看 Cloud 日志和错误报告

执行

每次运行脚本时,Apps 脚本都会记录执行情况,包括 Cloud 日志。这些记录可帮助您了解脚本执行了哪些操作。

如需在 Apps 脚本项目中查看脚本的执行情况,请点击左侧的执行情况图标

检查 Apps 脚本服务状态

虽然很少见,但有时特定的 Google Workspace 服务(例如 Gmail 或云端硬盘)会遇到暂时性问题,导致服务中断。发生这种情况时,与这些服务互动的 Apps 脚本项目可能无法按预期运行。

您可以查看 Google Workspace 状态信息中心,了解 Google Workspace 服务是否中断。 如果目前正发生服务中断,您可以等待问题解决,也可以在 Google Workspace 帮助中心Google Workspace 已知问题文档中寻求更多帮助。

使用调试程序和断点

如需查找脚本中的问题,您可以在调试模式下运行脚本。在调试模式下运行脚本时,当脚本到达断点(您在脚本中突出显示的可能存在问题的行)时,脚本会暂停。当脚本暂停时,它会显示每个变量在该时间点的值,让您无需添加大量日志记录语句即可检查脚本的内部运作情况。

添加断点

如需添加断点,请将鼠标悬停在要添加断点的行号上。点击行号左侧的圆圈。下图显示了向脚本添加断点的示例:

添加断点

在调试模式下运行脚本

如需在调试模式下运行脚本,请点击编辑器顶部的调试

在脚本运行包含断点的行之前,它会暂停并显示一个调试信息表。您可以使用此表检查参数值和存储在对象中的信息等数据。

如需控制脚本的运行方式,请使用调试器面板顶部的“步入”“步过”和“步出”按钮。借助这些工具,您可以逐行运行脚本,并检查值随时间的变化情况。

错误:当前行没有源代码

当前行没有源代码

当没有可用的有效调试文件时,系统会显示此错误。 Google Apps 脚本不支持在脚本编辑器中显示动态生成的 JavaScript (JS) 脚本,例如使用 eval()new Function() 生成的脚本。这些脚本在 V8 引擎中创建和执行,但在编辑器中不显示为独立文件。如果您单步执行这些脚本,就会遇到此错误。

例如,请参考以下代码:

function myFunction() {
  eval('a=2');
}

eval() 被调用时,其参数会被视为 JS 代码,并在 V8 引擎中作为动态创建的脚本运行。如果您步入 eval(),则会显示此错误。如果脚本包含 //# sourceURL 注释,则其名称会显示在调用堆栈中。否则,它会显示为未命名的条目。

尽管显示了错误消息,但调试会话仍处于活动状态,并且可以继续执行。如需继续,请继续执行单步进入、单步跳出或恢复执行。不过,只要执行仍处于动态脚本的范围内,此错误就会继续显示。执行移出动态脚本后,调试会继续进行,而不会出现此错误。

多个 Google 账号的问题

如果您同时登录多个 Google 账号,那么您可能无法正常访问插件和 Web 应用。 Apps 脚本、插件或 Web 应用不支持多重登录或同时登录多个 Google 账号。

  • 如果您在登录多个账号的情况下打开 Apps 脚本编辑器,Google 会提示您选择要继续使用的账号。

  • 如果您打开某个 Web 应用或插件时遇到多重登录问题,请尝试以下解决方案之一:

    • 退出您所有的 Google 账号,然后仅登录包含您要访问的插件或 Web 应用的账号。
    • 在 Google Chrome 中打开无痕式窗口或等效的无痕浏览窗口,然后登录包含您要访问的插件或 Web 应用的 Google 账号。

获取帮助

使用上述工具和技巧调试问题可以解决各种问题,但您可能会遇到一些需要额外帮助才能解决的问题。如需了解在何处提问和提交 bug,请参阅我们的支持页面