简体   繁体   English

如何解决 Google Apps 脚本开发中的常见错误

[英]How to solve common errors in Google Apps Script development

The Q&A is currently a subject of meta discussion, do participate.问答目前是讨论的主题,请参与。 The current plan is to split where possible into Q&As.目前的计划是尽可能分成问答环节。 Answers to the A&A are community wiki and the question should become one when the status is resolved. A&A 的答案是社区 wiki,当状态得到解决时,问题应该成为一个问题。


Preface前言

This Q&A strives to become a collection and a reference target for common errors encountered during development in Google Apps Script language in hopes to improve long-term maintainability of tag.本问答力求成为 Google Apps Script 语言开发过程中遇到的常见错误的集合和参考目标,以期提高标签的长期可维护性。

There are several similar and successful undergoings in other languages and general-purpose tags (see c++ , android , php , php again ), and this one follows suit. There are several similar and successful undergoings in other languages and general-purpose tags (see c++ , android , php , php again ), and this one follows suit.


Why it exists?为什么存在?

The amount of questions from both new and experienced developers regarding the meaning and solutions to errors encountered during development and production that can be effectively reduced to a single answer is substantial.新开发人员和经验丰富的开发人员提出的关于开发和生产过程中遇到的错误的含义和解决方案的问题数量很多,可以有效地简化为一个答案。 At the time of writing, even running a query only by language tag yields:在撰写本文时,即使仅通过语言标签运行查询也会产生:

  • "Cannot find method" 8 pages “找不到方法” 8 页
  • "Cannot read property" 9 pages “无法读取属性” 9 页
  • "Cannot call... in this context" 5 pages “在这种情况下无法调用...” 5 页
  • "You do not have permission" 11 pages “您没有权限” 11 页

Linking to a most relevant duplicate is hard and time-consuming for volunteers due to the need to consider nuances and often poorly-worded titles.由于需要考虑细微差别以及通常措辞不佳的标题,因此链接到最相关的副本对于志愿者来说既困难又耗时。


What it consists of?它由什么组成?

Entries in this Q&A contain are designed to provide info on how to:本问答包含的条目旨在提供有关如何:

  • parse the error message structure解析错误消息结构
  • understand what the error entails了解错误的含义
  • consistently reproduce (where applicable)持续复制(如适用)
  • resolve the issue解决问题
  • provide a link to canonical Q&A (where possible)提供规范问答的链接(如果可能)

Table of Contents目录

To help you navigate the growing reference please use the TOC below:为了帮助您浏览不断增长的参考资料,请使用以下目录:

  1. General errors一般错误
  2. Service-specific errors特定于服务的错误

What this is not?这不是什么?

The scope of the Q&A is limited to common (not trivial). Q&A 中的 scope 仅限于常见(并非微不足道)。 This is not:这不是:

  • a catch-all guide or "best practices" collection包罗万象的指南或“最佳实践”集合
  • a reference for general ECMAScript errors一般 ECMAScript 错误的参考
  • GAS documentation气体文件
  • a resources list (we have a tag wiki for that)资源列表(我们有一个标签 wiki

What to add?要添加什么?

When adding an entry, please, consider the following:添加条目时,请考虑以下事项:

  • is the error common enough (see "why" section for examples)?错误是否足够普遍(参见“为什么”部分的示例)?
  • can the solution be described concisely and be applicable for most cases?解决方案能否简明扼要地描述并适用于大多数情况?

Preface前言

The answer provides a guide on general errors that can be encountered when working with any Google service (both built-in and advanced) or API.答案提供了使用任何 Google 服务(内置和高级)或 API 时可能遇到的一般错误的指南。 For errors specific to certain services, see the other answer .对于特定于某些服务的错误,请参阅其他答案

Back to reference 返回参考


General errors一般错误


Message信息

TypeError: Cannot read property ' property name here ' from undefined (or null) TypeError:无法从未undefined (or null)中读取属性“ property name here

Description描述

The error message indicates that you are trying to access a property on an Object instance, but during runtime the value actually held by a variable is a special data type undefined .该错误消息表明您正在尝试访问Object实例上的属性,但在运行时,变量实际保存的值是一种特殊的数据类型undefined Typically, the error occurs when accessing nested properties of an object.通常,在访问 object 的嵌套属性时会发生错误。

A variation of this error with a numeric value in place of property name indicates that an instance of Array was expected.使用数值代替属性名称的此错误的变体表明需要Array的实例。 As arrays in JavaScript are objects , everything mentioned here is true about them as well.由于 JavaScript 中的 arrays 是对象,因此这里提到的所有内容也都是关于它们的。

There is a special case of dynamically constructed objects such as event objects that are only available in specific contexts like making an HTTP request to the app or invoking a function via time or event-based trigger.动态构造的对象有一种特殊情况,例如仅在特定上下文中可用的事件对象,例如向应用程序发出 HTTP 请求或通过时间或基于事件的触发器调用 function。

The error is a TypeError because an "object" is expected, but "undefined" is received错误是TypeError ,因为预期的是"object" ,但收到了"undefined"

How to fix怎么修

  1. Using default values使用默认值
    Logical OR || 逻辑或|| operator in JavaScript has an intersting property of evaluating the right-hand side iff the left-hand is falsy . JavaScript 中的运算符具有一个有趣的属性,即如果左侧为falsy则评估右侧。 Since objects in JS are truthy, and undefined and null are falsy, an expression like (myVar || {}).myProp [ (myVar || [])[index] for arrays] will guarantee that no error is thrown and the property is at least undefined .由于 JS 中的对象是真实的,而undefinednull是虚假的,因此像(myVar || {}).myProp [ (myVar || [])[index] for arrays] 这样的表达式将保证不会抛出错误并且属性至少是undefined的。

    One can also provide default values: (myVar || { myProp: 2 }) guarantees accessing myProp to return 2 by default.还可以提供默认值: (myVar || { myProp: 2 })保证访问myProp默认返回2 Same goes for arrays: (myVar || [1,2,3]) . arrays: (myVar || [1,2,3])也是如此。

  2. Checking for type检查类型
    Especially true for the special case, typeof operator combined with an if statement and a comparison operator will either allow a function to run outside of its designated context (ie for debugging purposes) or introduce branching logic depending on whether the object is present or not.对于特殊情况尤其如此, typeof 运算符结合if 语句比较运算符将允许 function 在其指定上下文之外运行(即用于调试目的)或引入分支逻辑,具体取决于 object 是否存在。

    One can control how strict the check should be:可以控制检查的严格程度:

  • lax ("not undefined"): if(typeof myVar;== "undefined") { //do something; } lax ("not undefined"): if(typeof myVar;== "undefined") { //do something; } if(typeof myVar;== "undefined") { //do something; }
  • strict ("proper objects only"): if(typeof myVar === "object" && myVar) { //do stuff } strict ("proper objects only"): if(typeof myVar === "object" && myVar) { //do stuff }

Related Q&As相关问答

  1. Parsing order of the GAS project as the source of the issue 解析 GAS 项目的顺序作为问题的来源

Message信息

Cannot convert some value to data type无法将some value转换为data type

Description描述

The error is thrown due to passing an argument of different type than a method expects.由于传递的参数类型与方法预期的不同,因此引发错误。 A common mistake that causes the error is accidental coercion of a number to string .导致错误的常见错误是将数字意外强制转换为字符串

How to reproduce如何重现

function testConversionError() {
  const ss = SpreadsheetApp.getActiveSheet();
  ss.getRange("42.0",1);
}

How to fix怎么修

Make sure that the value referenced in the error message is of data type required by documentation and convert as needed.确保错误消息中引用的值是文档要求的数据类型,并根据需要进行转换


Message信息

Cannot call Service and method name from this context无法从此上下文中调用Service and method name

Description描述

This error happens on a context mismatch and is specific to container-bound scripts.此错误发生在上下文不匹配且特定于容器绑定脚本的情况下。 The primary use case that results in the error is trying to call a method only available in one document type (usually, getUi() as it is shared by several services) from another (ie DocumentApp.getUi() from a spreadsheet).导致错误的主要用例是尝试从另一种(即电子表格中的DocumentApp.getUi()调用仅在一种文档类型中可用的方法(通常是getUi() ,因为它由多个服务共享)。

A secondary, but also prominent case is a result of calling a service not explicitly allowed to be called from a custom function (usually a function marked by special JSDoc-style comment @customfunction and used as a formula).次要但也是突出的情况是调用未明确允许自定义 function (通常是由特殊 JSDoc 样式注释@customfunction并用作公式的 function )调用的服务的结果。

How to reproduce如何重现

For bound script context mismatch, declare and run this function in a script project tied to Google Sheets (or anything other than Google Docs):对于绑定脚本上下文不匹配,请在与 Google 表格(或 Google 文档以外的任何内容)相关的脚本项目中声明并运行此 function:

function testContextMismatch() {
  const doc = DocumentApp.getUi();
}

Note that calling a DocumentApp.getActiveDocument() will simply result in null on mismatch, and the execution will succeed .请注意,调用DocumentApp.getActiveDocument()只会导致null不匹配,并且执行将成功

For custom functions, use the function declared below in any cell as a formula:对于自定义函数,使用下面在任何单元格中声明的 function 作为公式:

/**
 * @customfunction
 */
function testConversionError() {
  const ui = SpreadsheetApp.getUi();
  ui.alert(`UI is out of scope of custom function`);
}

How to fix怎么修

  1. Context mismatch is easily fixed by changing the service on which the method is called.上下文不匹配很容易通过更改调用该方法的服务来解决。
  2. Custom functions cannot be made to call these services, use custom menus or dialogs .无法使用自定义功能来调用这些服务,使用自定义菜单或对话框

Message信息

Cannot find method Method name here Method name here

The parameters param names do not match the method signature for method name参数param namesmethod name的方法签名不匹配

Description描述

This error has a notoriously confusing message for newcomers.这个错误对于新手来说是一个臭名昭著的令人困惑的信息。 What it says is that a type mismatch occurred in one or more of the arguments passed when the method in question was called.它说的是在调用相关方法时传递的一个或多个 arguments 中发生类型不匹配

There is no method with the signature that corresponds to how you called it, hence "not found"没有与您的调用方式相对应的签名方法,因此“未找到”

How to fix怎么修

The only fix here is to read the documentation carefully and check if order and inferred type of parameters are correct (using a good IDE with autocomplete will help).此处唯一的解决方法是仔细阅读文档并检查参数的顺序和推断类型是否正确(使用具有自动完成功能的良好 IDE 会有所帮助)。 Sometimes, though, the issue happens because one expects the value to be of a certain type while at runtime it is of another.但是,有时会发生问题,因为人们期望值是某种类型,而在运行时它是另一种类型。 There are several tips for preventing such issues:有几个技巧可以防止此类问题:

  1. Setting up type guards ( typeof myVar === "string" and similar).设置类型保护( typeof myVar === "string"和类似的)。
  2. Adding a validator to fix the type dynamically thanks to JavaScript being dynamically typed .由于 JavaScript 是动态类型的,因此添加了一个验证器来动态修复类型

Sample样本

 /** * @summary pure arg validator boilerplate * @param {function (any): any} * @param {...any} args * @returns {any[]} */ const validate = (guard, ...args) => args.map(guard); const functionWithValidator = (...args) => { const guard = (arg) => typeof arg?== "number": parseInt(arg); arg, const [a,b,c] = validate(guard. ..;args), const asObject = { a, b; c }. console;log(asObject); return asObject; }, //driver IIFE (() => { functionWithValidator("1 apple",2;"0x5"); })()


Messages留言

You do not have permission to perform that action您无权执行该操作

The script does not have permission to perform that action该脚本无权执行该操作

Description描述

The error indicates that one of the APIs or services accessed lacks sufficient permissions from the user.该错误表明访问的 API 或服务之一缺乏来自用户的足够权限。 Every service method that has an authorization section in its documentation requires at least one of the scopes to be authorized.在其文档中具有授权部分的每个服务方法都需要至少一个要授权的范围。

As GAS essentially wraps around Google APIs for development convenience, most of the scopes listed in OAuth 2.0 scopes for APIs reference can be used, although if one is listed in the corresponding docs it may be better to use it as there are some inconsistencies.由于 GAS 本质上为方便开发而封装了 Google API,因此可以使用 OAuth 2.0 范围内的 API 参考范围中列出的大多数范围,但如果在相应的文档中列出了一个范围,则使用它可能会更好,因为存在一些不一致之处。

Note that custom functions run without authorization.请注意,自定义函数在未经授权的情况下运行。 Calling a function from a Google sheet cell is the most common cause of this error.从 Google 表格单元格调用 function 是导致此错误的最常见原因。

How to fix怎么修

If a function calling the service is ran from the script editor, you are automatically prompted to authorize it with relevant scopes.如果从脚本编辑器运行调用服务的 function,系统会自动提示您使用相关范围对其进行授权。 Albeit useful for quick manual tests, it is best practice to set scopes explicitly in application manifest (appscript.json).尽管对快速手动测试很有用,但最好在应用程序清单 (appscript.json) 中明确设置范围 Besides, automatic scopes are usually too broad to pass the review if one intends to publish the app.此外,如果打算发布应用程序,自动范围通常太宽而无法通过审核

The field oauthScopes in manifest file ( View -> Show manifest file if in code editor) should look something like this:清单文件中的oauthScopes字段(如果在代码编辑器中,则View -> Show manifest file )应如下所示:

  "oauthScopes": [
    "https://www.googleapis.com/auth/script.container.ui",
    "https://www.googleapis.com/auth/userinfo.email",
    //etc
  ]

For custom functions, you can fix it by switching to calling the function from a menu or a button as custom functions cannot be authorized .对于自定义功能,您可以通过切换到从菜单或按钮调用function来修复它, 因为自定义功能无法授权

For those developing editor Add-ons , this error means an unhandled authorization lifecycle mode: one has to abort before calls to services that require authorization in case auth mode is AuthMode.NONE .对于那些开发编辑器插件的人来说,这个错误意味着一个未处理的授权生命周期模式:如果 auth 模式是AuthMode.NONE ,则必须在调用需要授权的服务之前中止。

Related causes and solutions相关原因及解决方法

  1. @OnlyCurrentDoc limiting script access scope @OnlyCurrentDoc 限制脚本访问scope
  2. Scopes autodetection范围自动检测

Message信息

ReferenceError: service name is not defined ReferenceError:未定义service name

Description描述

The most common cause is using an advanced service without enabling it.最常见的原因是使用高级服务而不启用它。 When such a service is enabled, a variable under the specified identifier is attached toglobal scope that the developer can reference directly.启用此类服务后,将指定标识符下的变量附加到全局 scope ,开发人员可以直接引用该变量。 Thus, when a disabled service is referenced, a ReferenceError is thrown.因此,当引用禁用的服务时,会引发ReferenceError

How to fix怎么修

Go to "Resources -> Advanced Google Services" menu and enable the service referenced. Go 到“资源 -> 高级 Google 服务”菜单并启用引用的服务。 Note that the identifier should equal the global variable referenced.请注意,标识符应等于引用的全局变量。 For a more detailed explanation, read the official guide .更详细的解释,请阅读官方指南

If one hasn't referenced any advanced services then the error points to an undeclared variable being referenced.如果没有引用任何高级服务,则错误指向一个未声明的变量被引用。


Message信息

The script completed but did not return anything.脚本完成但没有返回任何内容。

Script function not found: doGet or doPost找不到脚本 function: doGet or doPost

Description描述

This is not an error per se (as the HTTP response code returned is 200 and the execution is marked as successful, but is commonly regarded as one. The message appears when trying to make a request/access from browser a script deployed as a Web App .这本身不是错误(因为返回的 HTTP 响应代码为200并且执行被标记为成功,但通常被认为是一个错误。尝试从浏览器发出请求/访问脚本时出现该消息部署为 Web应用程序

There are two primary reasons why this would happen:发生这种情况的主要原因有两个:

  1. There is no doGet or doPost trigger function没有doGetdoPost触发器 function
  2. Triggers above do not return an HtmlOutput or TextOutput instance上面的触发器不返回HtmlOutputTextOutput实例

How to fix怎么修

For the first reason, simply provide a doGet or doPost trigger (or both) function.对于第一个原因,只需提供doGetdoPost触发器(或两者)function。 For the second, make sure that all routes of your app end with creation of TextOutput or HtmlOutput :其次,确保您的应用程序的所有路由都以创建TextOutputHtmlOutput结束:

//doGet returning HTML
function doGet(e) {
  return HtmlService.createHtmlOutput("<p>Some text</p>");
}

//doPost returning text
function doPost(e) {
  const { parameters } = e;
  const echoed = JSON.stringify(parameters);
  return ContentService.createTextOutput(echoed);
}

Note that there should be only one trigger function declared - treat them as entry points to your application.请注意,应该只声明一个触发器 function - 将它们视为应用程序的入口点。

If the trigger relies on parameter / parameters to route responses, make sure that the request URL is structured as " baseURL /exec? query " or " baseURL /dev? query " where query contains parameters to pass .如果触发器依赖parameter / parameters来路由响应,请确保请求 URL 的结构为“ baseURL /exec? query ”或“ baseURL /dev? query ”,其中query包含要传递的参数

Related Q&As相关问答

  1. Redeploying after declaring triggers声明触发器后重新部署

Message信息

We're sorry, a server error occurred.很抱歉,发生服务器错误。 Please wait a bit and try again.请稍等,然后重试。

Description描述

This one is the most cryptic error and can occur at any point with nearly any service (although DriveApp usage is particularly susceptible to it).这是最神秘的错误,几乎可以在任何服务的任何时候发生(尽管DriveApp的使用特别容易受到它的影响)。 The error usually indicates a problem on Google's side that either goes away in a couple of hours/days or gets fixed in the process.该错误通常表明谷歌方面的问题在几个小时/几天内消失或在此过程中得到修复。

How to fix怎么修

There is no silver bullet for that one and usually, there is nothing you can do apart from filing an issue on the issue tracker or contacting support if you have a GSuite account.对于那个没有灵丹妙药,通常,除了在问题跟踪器上提交问题或联系支持人员(如果您有 GSuite 帐户)之外,您无能为力。 Before doing that one can try the following common remedies:在这样做之前,可以尝试以下常见的补救措施:

  1. For bound scripts - creating a new document and copying over the existing project and data.对于绑定脚本 - 创建新文档并复制现有项目和数据。
  2. Switch to using an advanced Drive service (always remember to enable it first).切换到使用高级Drive服务(始终记得先启用它)。
  3. There might be a problem with a regular expression if the error points to a line with one.如果错误指向带有 1 的行, 则正则表达式可能存在问题

Don't bash your head against this error - try locating affected code, file or star an issue and move on不要 bash 反对这个错误 - 尝试定位受影响的代码、文件或为问题加注星标并继续


Syntax error without apparent issues没有明显问题的语法错误

This error is likely to be caused by using an ES6 syntax (for example, arrow functions) while using the deprecated V8 runtime (at the time of writing the GAS platform uses V8 ).此错误可能是由于在使用已弃用的 V8 运行时(在编写 GAS 平台时使用 V8时)使用 ES6 语法(例如,箭头函数)引起的。

How to fix怎么修

Open "appscript.json" manifest file and check if runtimeVersion is set to "V8" , change it if not, or remove any ES6 features otherwise.打开 "appscript.json" 清单文件并检查runtimeVersion是否设置为"V8" ,如果没有则更改,否则删除任何ES6 功能


Quota-related errors配额相关错误

There are several errors related to quotas imposed on service usage.有几个与对服务使用的配额有关的错误。 Google has a comprehensive list of those, but as a general rule of thumb, if a message matches "too many" pattern, you are likely to have exceeded the respective quota.谷歌有一个完整的列表,但作为一般的经验法则,如果一条消息匹配“太多”模式,你很可能已经超出了相应的配额。

Most likely errors encountered:最可能遇到的错误:

  • Service invoked too many times: service name服务调用次数过多: service name
  • There are too many scripts running运行的脚本太多
  • Service using too much computer time for one day一天使用过多计算机时间的服务
  • This script has too many triggers此脚本的触发器过多

How to fix怎么修

In most cases, the only fix is to wait until the quota is refreshed or switch to another account (unless the script is deployed as a Web App with permission to "run as me", in which case owner's quotas will be shared across all users).在大多数情况下,唯一的解决方法是等到配额刷新或切换到另一个帐户(除非脚本部署为 Web 应用程序并具有“以我身份运行”的权限,在这种情况下,所有者的配额将在所有用户之间共享)。

To quote documentation at the time:要引用当时的文档:

Daily quotas are refreshed at the end of a 24-hour window;每日配额在 24 小时 window 结束时刷新; the exact time of this refresh, however, varies between users.但是,此刷新的确切时间因用户而异。

Note that some services such as MailApp have methods like getRemainingDailyQuota that can check the remaining quota.请注意,某些服务(例如MailApp )具有诸如getRemainingDailyQuota之类的方法,可以检查剩余配额。

In the case of exceeding the maximum number of triggers one can check how many are installed via getProjectTriggers() (or check "My triggers" tab) and act accordingly to reduce the number (for example, by using deleteTrigger(trigger) to get rid of some).在超过触发器的最大数量的情况下,可以通过getProjectTriggers()检查安装了多少(或检查“我的触发器”选项卡)并采取相应措施减少数量(例如,通过使用deleteTrigger(trigger)摆脱一些中的)。

Related canonical Q&As相关规范问答

  1. How are daily limitations being applied and refreshed? 如何应用和更新每日限制?
  2. "Maximum execution time exceeded" problem “超过最大执行时间” 问题
  3. Optimizing service calls to reduce execution time 优化服务调用以减少执行时间

References参考

  1. How to make error messages more meaningful如何让错误信息更有意义
  2. Debugging custom functions调试自定义函数

Service-specific errors特定于服务的错误

The answer concerns built-in service -related errors.答案涉及与内置服务相关的错误。 For general reference see the other answer .有关一般参考,请参阅其他答案 Entries addressing issues with services listed in official reference are welcome.欢迎提交解决官方参考中列出的服务问题的条目。

Back to reference 返回参考


SpreadsheetApp电子表格应用程序

The number of rows in the range must be at least 1范围内的行数必须至少为 1

This error is usually caused by calling the getRange method where the parameter that sets the number of rows happens to equal to 0 .此错误通常是由调用getRange方法引起的,其中设置行数的参数恰好等于0 Be careful if you depend on getLastRow() call return value - only use it on non-empty sheets ( getDataRange will be safer).如果您依赖getLastRow()调用返回值,请小心 - 仅在非空工作表上使用它( getDataRange会更安全)。

How to reproduce如何重现

sh.getRange(1, 1, 0, sh.getLastColumn()); //third param is the number of rows

How to fix怎么修

Adding a guard that prevents the value from ever becoming 0 should suffice.添加一个防止值变为0的保护就足够了。 The pattern below defaults to the last row with data (optional if you only need a certain number of rows) and to 1 if that also fails:下面的模式默认为包含数据的最后一行(如果您只需要一定数量的行,则为可选),如果也失败,则为1

//willFail is defined elsewhere
sh.getRange(1, 1, willFail || sh.getLastRow() || 1, sh.getLastColumn());

Error: “Reference does not exist”错误:“参考不存在”

The error happens when calling a custom function in a spreadsheet cell that does not return a value .不返回值的电子表格单元格中调用自定义 function 时会发生错误。 The docs do mention only that one "must return a value to display", but the catch here is that an empty array is also not a valid return value (no elements to display).文档确实只提到了一个“必须返回要显示的值”,但这里的问题是空数组也不是有效的返回值(没有要显示的元素)。

How to reproduce如何重现

Call the custom function below in any Google Sheets spreadsheet cell:在任何 Google 表格电子表格单元格中调用以下自定义 function:

/**
 * @customfunction
 */
const testReferenceError = () => [];

How to fix怎么修

No specific handling is required, just make sure that length > 0 .无需特殊处理,只需确保length > 0即可。


The number of rows or cells in the data does not match the number of rows or cells in the range.数据中的行数或单元格数与范围内的rows or cells rows or cells不匹配。 The data has N but the range has M .数据有N但范围有M

Description描述

The error points to a mismatch in dimensions of range in relation to values.该错误表明范围维度与值的不匹配 Usually, the issue arises when using setValues() method when the matrix of values is smaller or bigger than the range.通常,当值矩阵小于或大于范围时,使用setValues()方法会出现问题。

How to reproduce如何重现

function testOutOfRange() {
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const sh = ss.getActiveSheet();
    const rng = sh.getActiveRange();
    const vals = rng.getValues();
    
    try {
        vals.push([]);
        rng.setValues(vals);
    } catch (error) {
        const ui = SpreadsheetApp.getUi();
        ui.alert(error.message);
    }
}

How to fix怎么修

If it is routinely expected for values to get out of bounds, implement a guard that catches such states, for example:如果通常期望值超出范围,请实现一个捕捉此类状态的守卫,例如:

const checkBounds = (rng, values) => {
    const targetRows = rng.getHeight();
    const targetCols = rng.getWidth();

    const { length } = values;
    const [firstRow] = values;

    return length === targetRows &&
        firstRow.length === targetCols;
};

The coordinates of the range are outside the dimensions of the sheet.该范围的坐标在工作表的尺寸之外。

Description描述

The error is a result of a collision between two issues:该错误是两个问题之间发生冲突的结果:

  1. The Range is out of bounds ( getRange() does not throw on requesting a non-existent range) Range超出范围( getRange()不会在请求不存在的范围时抛出)
  2. Trying to call a method on a Range instance referring to a non-existent dimension of the sheet.试图在Range实例上调用引用不存在的工作表维度的方法。

How to reproduce如何重现

function testOB() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getActiveSheet();
  const rng = sh.getRange(sh.getMaxRows() + 1, 1);
  rng.insertCheckboxes();
}

How to fix怎么修

Check that number of rows ( getMaxRow() ) and columns ( getMaxColumns() ) are both greater or equal to the parameters passed to getRange() method call and change them accordingly.检查行数 ( getMaxRow() ) 和列数 ( getMaxColumns() ) 是否都大于或等于传递给getRange()方法调用的参数,并相应地更改它们。


Exception: You can't create a filter in a sheet that already has a filter.例外:您不能在已有过滤器的工作表中创建过滤器。

Description描述

The message means that you are trying to call a createFilter method on a Range in a Sheet that already has a filter set (either via UI or script), thus violating the restriction on 1 filter per Sheet , to quote the documentation:该消息意味着您正在尝试在已经具有过滤器集(通过 UI 或脚本)的Sheet中的Range上调用createFilter方法,从而违反了对每个Sheet 1 个过滤器的限制,以引用文档:

There can be at most one filter in a sheet.一张表中最多可以有一个过滤器。

How to reproduce如何重现

const testFilterExistsError = () => {
  const sh = SpreadsheetApp.getActiveSheet();  
  const rng = sh.getDataRange();
  
  const filter1 = rng.createFilter();
  const filter2 = rng.createFilter();
};

How to fix怎么修

Add a guard that checks for the existence of the filter first.添加一个守卫,首先检查过滤器是否存在。 getFilter returns either a filter or null if called on a Range instance and is perfect for the job:如果在Range实例上调用getFilter ,则返回过滤器或null并且非常适合该工作:

const testFilterGuard = () => {
  const sh = SpreadsheetApp.getActiveSheet();  
  const rng = sh.getDataRange();
  
  const filter = rng.getFilter() || rng.createFilter();
  //do something useful;
};

UrlFetchApp UrlFetchApp

Attribute provided with no value: url无值提供的属性:url

Description描述

The error is specific to UrlFetchApp service and happens when fetch or fetchAll method gets called with an empty string or non-string value.该错误特定于UrlFetchApp服务,并且在使用空字符串或非字符串值调用fetchfetchAll方法时发生。

How to reproduce如何重现

const response = UrlFetchApp.fetch("", {});

How to fix怎么修

Make sure that a string containing a URI (not necessarily valid) is passed to the method as its first argument.确保将包含 URI(不一定有效)的字符串作为其第一个参数传递给该方法。 As its common root cause is accessing a non-existent property on an object or array , check whether your accessors return an actual value.由于其常见的根本原因是访问object 或数组上不存在的属性,因此请检查您的访问器是否返回实际值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM