问题排查

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

错误消息

当脚本遇到错误时,系统会显示一条包含行号的错误消息。错误分为两种基本类型:语法错误和运行时错误。

语法错误

当代码不符合 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 行末尾缺少 ) 字符。保存脚本时,系统会显示以下错误:

实参列表后缺少“)”。(第 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);
}

虽然代码格式正确,但“john”是无效的电子邮件地址。系统会抛出以下错误:

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

这些错误之所以难以解决,是因为数据通常是从电子表格或表单等外部来源提取的。使用调试技术来确定原因。

常见错误

以下是常见错误及其原因的列表。

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

此错误表示您已超出某项操作(例如发送过多电子邮件)的每日配额。配额因账号类型而异,并且可能会随时更改。 如需查看限额,请参阅 Apps 脚本配额文档。

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

可能的原因包括:

  • Google 服务器暂时不可用。请稍后再试。
  • 脚本中的错误缺少相应的消息。尝试进行调试以找出问题。
  • Google Apps 脚本中存在 bug。在 Bugs 中搜索并提交 bug 报告。

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

脚本缺少运行所需的授权。当脚本通过触发器运行或作为服务运行时,无法显示授权对话框。

如需授权脚本,请打开脚本编辑器并运行任意函数。如果脚本使用了新的未经授权的服务,您必须重新授权。

在授权之前或过期之后触发的触发器通常会导致此错误。如果某个插件导致了此问题,请再次使用该插件重新授权。移除有问题的触发器:

  1. 在 Apps 脚本项目中,点击触发器图标 。
  2. 在触发器旁边,依次点击更多图标 >“删除触发器”。

或者,您也可以卸载该插件。

精细权限也可能会导致这些错误。如需了解如何保护触发器执行,请参阅授权范围页面。

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

Google Workspace 管理员可以为其网域停用 Drive API,从而阻止用户使用使用 Drive 服务的云端硬盘应用或 Apps 脚本插件。

如果插件或 Web 应用是针对网域范围的安装而发布的,并且由管理员安装,那么即使 Drive API 已停用,脚本也能正常运行。

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

活跃用户的身份和电子邮件地址不可用。这是在授权模式(而非 AuthMode.FULL)下调用 Session.getActiveUser() 或 Session.getEffectiveUser() 导致的。 如果您的脚本通过触发器运行,您可以在 Apps 脚本事件对象的 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 管理员可以使用许可名单来控制外部网域访问权限。请与您的管理员联系,将相应网址添加到许可名单中。

违反“权限”政策

当使用 HTMLService 的应用尝试执行需要敏感权限的 Web API 时,就会发生此错误,例如需要摄像头或麦克风访问权限的 navigator.mediaDevices.getUserMedia()。Apps 脚本沙盒环境会限制这些功能,以保护用户安全。

在单独的网域(Apps 脚本之外)上托管需要这些权限的功能,并在新窗口或标签页中打开该功能。 然后,您可以将捕获的数据或响应发布回 Apps 脚本应用,如本例所示。

Code.gs

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('Index')
      .setTitle('Media Devices Example');
}
function processCameraData(data) {
  Logger.log('Received data from client-side: ' + data);
  // Process data as needed
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <button id="open-camera">Open Camera in New Window</button>
    <script>
      document.getElementById('open-camera').addEventListener('click', function() {
        // URL for external domain handling camera access & posting data back.
        // External page uses getUserMedia & window.opener.postMessage(...).
        var externalUrl = 'https://your-external-domain.com/camera';
        window.open(externalUrl, 'cameraWindow', 'width=600,height=400');
      });

      // Listen for messages from the external window.
      window.addEventListener('message', function(event) {
        // Check event.origin to ensure message is from the expected source.
        if (event.origin !== 'https://your-external-domain.com') {
          return;
        }
        console.log('Data received from external window:', event.data);
        // Send data to server-side Apps Script.
        google.script.run.processCameraData(event.data);
      });
    </script>
  </body>
</html>

<Class> / Apiary.<Service Name> 已停用。请与您的管理员联系以启用此功能

如果管理员已为数据区域启用高级设置,则会发生此错误。 有些 Apps 脚本功能依赖于在全球范围内处理数据的服务。 因此,在需要遵守特定数据区域政策的情况下,部分功能可能无法正常运行。 如果您使用的任何 Apps 脚本类或高级服务需要进行全球数据处理,您的脚本可能会遇到类似于以下屏幕截图的错误消息:

已停用的类调用

调试

有些错误很细微,不会触发消息。例如,您的代码可能能够执行,但结果不符合预期。 使用以下策略来调查行为异常的脚本。

日志记录

在脚本编辑器中使用 Cloud Logging 服务或 Logger 和控制台服务,在脚本执行时记录信息。

如果管理员已为数据区域启用高级设置,并且您的部分脚本是在 2018 年之前创建的,您可能会看到一条消息,指出关联的云项目已停止 Cloud Logging,以符合数据区域化要求。

日志禁止显示通知

Error Reporting

如需在 Google Cloud 中使用 Error Reporting,请使用标准的用户管理型项目,而不是默认项目。

使用标准项目时,系统会自动在 Google Cloud Error Reporting 中记录运行时错误。 在 Google Cloud 控制台中查看 Cloud 日志和错误报告。

执行

Google Apps 脚本会记录每次执行,包括云日志。如需查看执行情况,请点击执行图标 。

检查服务状态

在 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。