Google script DriveApp.getFolders().hasNext() error

980 views Asked by At

I want to create a directory in the drive if it doesn't already exist.

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

The function stops when the condition is reached:

Sorry, a server error has occurred. Please wait a bit and try again.

What is the problem and how can it be fixed?

2

There are 2 answers

1
Marios On

There is nothing wrong with your code.

Google can not guarantee 100% service availability.

Explanation:

The error tells you that you need to wait a little bit before your execute that function again.

A potential workaround solution would be to use a try...catch statement and within the catch brackets include a code to automatically execute the function after some time.

For example, you can create a time-driven trigger that executes CreateDirectory() after some time (e.g. 1 minute) if the function failed the first time.


Solution:

In the following solution the logic is to manually execute the toRun() function. The latter will try to execute CreateDirectory(). If an error occurs, it will create a time-driven trigger that will execute CreateDirectory() after a minute (modify that to your needs). The clearTrigger() function is responsible for clearing all the previous triggers (if there are any) that are created because of that code.

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]);
  }
}
}
14
Mateo Randwolf On

Server errors might occur when you make requests. To solve these type of unexpected errors you can apply exponential backoff, a technique that basically tries to run the request you are asking for a number of times. If the request still gets an error like the one you are getting, then this technique catches this error and waits a certain amount of time before asking again for this request. This will avoid the network congestion causing the unexpected error.

In your example exponential backoff can be achieved using the following piece of code (it has self-explanatory comments):

// 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);
}

Reference:

Utilities.sleep()

Exponential backoff in Google Cloud

Exponential backoff