【问题标题】:Google script DriveApp.getFolders().hasNext() error谷歌脚本 DriveApp.getFolders().hasNext() 错误
【发布时间】:2021-01-19 18:40:18
【问题描述】:

如果驱动器中不存在目录,我想创建一个目录。

function CreateDirectory() {
  var folderName="Example";
  var Directory;
  var fi = DriveApp.getFoldersByName(folderName);
  if (fi.hasNext()) {
    Directory = fi.next();
  } else {
    Directory = DriveApp.createFolder(folderName);
  }
}

达到条件时函数停止:

抱歉,出现服务器错误。请稍等,然后重试。

问题是什么,如何解决?

【问题讨论】:

  • 您的代码没有问题。 Google 无法提供 100% 的服务可用性。您可以做的是使用 try-catch 语句,并在 catch 括号内包含延迟此过程的代码(时间触发器或睡眠或类似的东西)
  • 如错误信息所说,稍等一下再试一次。
  • 嗨@Marios,您能否将您的评论正式化为对此帖子的回答,以便遇到类似错误消息的其他用户可以轻松找到解决方案?谢谢!
  • 这能回答你的问题吗? stackoverflow.com/questions/64079595/…
  • 是的,如果我将它复制到另一个项目,它可以工作。我最初是从另一个项目复制到这里的,但在这里不起作用。无论我想在哪个项目中使用代码都不是我的财产,我只是一个编辑器。因此,我不能把它放到一个新项目中(或者我不知道如何解决它)但是,我认为我不需要为此创建一个新项目并复制数千行然后重新- 授权多个帐户。

标签: google-apps-script google-drive-api server-error


【解决方案1】:

您的代码没有问题。

Google 无法保证 100% 的服务可用性。

说明:

错误告诉您在再次执行该函数之前需要等待一点。

一个潜在的解决方法解决方案是使用try...catch 语句,并在catch 括号内包含一个代码以在一段时间后自动执行函数

例如,您可以创建一个time-driven 触发器,如果函数第一次失败,它会在一段时间(例如1分钟)后执行CreateDirectory()


解决方案:

在下面的解决方案中,逻辑是手动执行toRun()函数。后者将尝试执行CreateDirectory()。如果发生错误,它将创建一个时间驱动的触发器,该触发器将在一分钟后执行CreateDirectory()(根据您的需要进行修改)。 clearTrigger() 函数负责清除所有之前因该代码而创建的触发器(如果有)。

function toRun(){

  try{
    CreateDirectory();
  }
  
  catch (e){
    
     clearTrigger(); // clear previous created triggers
     ScriptApp.newTrigger("CreateDirectory") 
     .timeBased()
     .after(1 * 60 * 1000) // execute CreateDirectory after 1 minute
     .create();
  } 
 
}

function CreateDirectory() {
  var folderName="Example";
  var Directory;
  var fi = DriveApp.getFoldersByName(folderName);
  if (fi.hasNext()) {
    Directory = fi.next();
  } else {
    Directory = DriveApp.createFolder(folderName);
  }
}

function clearTrigger(){

var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
  if (triggers[i].getHandlerFunction() == "CreateDirectory") {
    ScriptApp.deleteTrigger(triggers[i]);
  }
}
}

【讨论】:

  • 不幸的是,解决方案并不好。我有时尝试了几个小时,但从未正确运行。问题总是一样的:“if (fi.hasNext())” 还有另一个谷歌表,其中相同的代码总是运行没有错误。会不会是权限问题?
  • @GáborRaczky 复制您的文件(其中包含您正在使用的脚本)并在执行此代码时使用它。让我知道这是否有效。如果是,请单击答案左侧的勾选按钮将答案标记为已接受。
【解决方案2】:

当您发出请求时,可能会发生服务器错误。要解决这些类型的意外错误,您可以应用指数退避,这是一种基本上尝试运行您多次请求的请求的技术。如果请求仍然收到与您收到的错误类似的错误,则此技术会捕获此错误并等待一定时间,然后再次请求此请求。这将避免网络拥塞导致意外错误。

在您的示例中,可以使用以下代码实现指数退避(它具有不言自明的 cmets):

// Function that implements exponential backoff
function myFuncion(){
  var folderName="Example";
  var Directory;
  
  var fi = DriveApp.getFoldersByName(folderName);

  // Try making the request 50 times (you can change this to n number of times)
  for(i=0;i<50;i++){
    try{
      if (fi.hasNext()) {
          Directory = fi.next();
      } else {
              Directory = DriveApp.createFolder(folderName);
             }
       break;
      // If successful you get out of the loop and run your function correctly
      // Otherwise wait for an exponential amount of time before making the request again
    }catch(e){
      Utilities.sleep((Math.pow(2,i)*1000) + (Math.round(Math.random() * 100)));
    }
    
  }
  Logger.log(Directory);
}

参考:

Utilities.sleep()

Exponential backoff in Google Cloud

Exponential backoff

【讨论】:

  • 正如我已经写的那样,即使我多次运行代码,它总是会出错。 :(
  • 在我的实施过程中,您仍然收到服务器错误消息吗?你还在这行代码if(fi.hasNext()) 上遇到这个错误吗?您能否在执行返回错误Logger.log(fi) 的代码行之前记录fi
  • 是的,发生服务器错误... Logger.log(fi) 结果:[20-10-27 14:51:02:373 CET] FolderIterator
  • 嗨!我已经编辑了我的答案,你可以试试我更新的代码,看看你是否仍然得到同样的错误?谢谢 ! :D
  • 不工作,fi.hasNext() 总是出错。在另一个项目中工作。我不明白。 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
相关资源
最近更新 更多