Failure reports in timed triggers in Google apps script - google-apps-script

I use the following timed trigger on a Google Spreadsheet. It runs every ten minutes:
function timedTriggerWatchFiles(rootFolder) {
// make an array with all the names of the childfolder
if (DriveApp.getFoldersByName(rootFolder).hasNext()) {
var childFolders = DriveApp.getFoldersByName(rootFolder).next().getFolders();
}
var childFoldersA = [];
while (childFolders.hasNext()) {
childFoldersA.push(childFolders.next().getName());
}
// run watchfiles for each child folder
for ( var i=0 ; i < childFoldersA.length ; i++) {
watchFiles(rootFolder, childFoldersA[i]);
}
}
function timedTrigger() {
timedTriggerWatchFiles("folder");
}
At least once a day I get a 'failure report' in my Inbox, saying:
We're sorry, a server error occurred. Please wait a bit
and try again. (line 242, file "Code")
The execution log gives the following message:
[14-01-22 17:29:38:363 CET] Execution failed: We're sorry,
a server error occurred. Please wait a bit and try again.
(line 242, file "Code") [37.016 seconds total runtime]
The lines are always different, but also always contain the function hasNext(). This is line 242:
while (childFolders.hasNext()) {
What am I doing wrong here? My script works as it is supposed to work. I just don't understand why I am receiving the error messages.

In the Drive SDK documentation there is a section about exponential backoff that you should check out. You could try the GASRetry library to simplify this in Apps Script.

#Greg's answer points to all the right resources for working with APIs in Google Apps Scripts.
Although it may appear that access to things like ScriptDB, DriveApp, SpreadsheetApp etc is native to Apps Scripts, in fact there are access limitations for aggressive use. The simplest of solutions is Utilities.sleep(1000);.
However, if you have a script that is running tightly within the 600 second limit, or you need to ensure that every request is made as quickly as possibly, then the resources in #Greg's answer will be of great assistance.

Related

suddenly I get the error: Cannot find method setMimeType((class)) without any change

Suddenly my script get the error:
Cannot find method setMimeType((class)) (line xxx, file "Code")
It worked well for years, until this afternoon. I didn't modified it at all.
What I've done after:
copied this code from google documentation:
function doGet() {
var feed = UrlFetchApp.fetch('http://xkcd.com/rss.xml').getContentText();
feed = feed.replace(
/(<img.*?alt="(.*?)".*?>)/g,
'$1' + new Array(10).join('<br />') + '$2');
return ContentService.createTextOutput(feed)
.setMimeType(ContentService.MimeType.RSS);
}
pasted it into a new script
given it the proper authorizations
run it
It was ok.
Then:
renamed the doGet() function into doGet1() in my broken script
pasted the example doGet() function code
run my script (doGet function)
I obtained the same error:
Cannot find method setMimeType((class)) (line xxx, file "Code")
What could have happened?
i just had the same error. my script stopped working.
it looks like the "ContentService.MimeType.RSS" does no longer exist.
"RSS" is no longer an autocomplete option if you type that.
i changed it to the "ContentService.MimeType.TEXT".
it is the closest option.
i also had to make a new deployment after saving the new code.
now my script is working again.
Trying to debug my script, a message informed me that my project uses an old Apps Script runtime, and that in order to execute debug I have to upgrade to Javascript V8 engine. After doing that, everything went back to normal.
I attach a screenshot (from a different script, in Italian language).

Inserting Image into Google Sheets from Google Drive using Apps Script

I have been trying for 9 days to add an image that is uploaded to my drive (via the use of a google form) into my Google sheet using Apps Script, but it isn't working and I have no idea why, this is my code below:
function getImage(){
var folderImage = DriveApp.getFolderById("0B7gxdApLS0TYfm1pRHpHSG4yTm96bm1PbTZQc1VmdGpxajY4N1J4M1gtR1BiZ0lOSl9NMjQ");
Logger.log(folderImage.getFiles().next().setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW));
Logger.log(folderImage.getFiles().next().getSharingAccess());
Logger.log(folderImage.getFiles().next().getSharingPermission());
var imageFile = folderImage.getFiles().next().getBlob();
detailSheet.insertImage(imageFile, 1, 13);
}
I have even tried making the sharing and access permissions of the to be as open as possible but I keep getting this error message:
"We're sorry, a server error occurred. Please wait a bit and try again"
I find the error message ambiguous which leads me at a dead end. Usually the message gives me a good idea of where I have gone wrong.
I believe my code is correct, and during my research I have found no definitive reason this shouldn't work. Does anybody know where I am going wrong?
A solution would be great but preferably a critique on my code so I can learn :)
Couple of issues with your script:
You never bind to a specific file, so to work with the same file you have to reinitialize the iterator each time.
You don't verify its mimetype prior to using it as an image
An example that resolves those issues:
function addFolderPNGs_(sheet, folderId) {
const folder = folderId ? DriveApp.getFolderById(folderId) : DriveApp.getRootFolder(); // scope only to the root or given folder.
const imgs = folder.getFilesByType(MimeType.PNG);
var targetRow = sheet.getLastRow();
while (imgs.hasNext()) {
var img = imgs.next();
Logger.log(img.getName())
sheet.insertImage(img.getBlob(), 1, ++targetRow);
}
}
References
getFilesByType is either folder-specific (above) or operates on all of Google Drive
DriveApp
Folder
MimeTypes
Sheet#insertImage

Drive API - file or folder access timeout

I have a simple script to get files from Drive and print. When I run this it runs for about 400-500 seconds and I am getting timeout error.
I have two google accounts. Same script works in account-1(testing account) but not in account-2(main account).
Any help in isolating this issue would be more helpful.
Tried stepping through debugger the control comes back again and again to line-4 (file.hasNext()). How do I debug and make this script work?
My goal: to open specific file in the drive given a file name.
function myHelloWorld() {
Logger.log("Hello world\n");
var files = DriveApp.getFiles();
if (files.hasNext()) {
Logger.log("There are files\n");
}
}
Note:
1) Permission to run this script in both accounts were allowed (as part of first run).
2) No log messages were generated (View->Logs)
3) Timeout error was found in (View->Execution transcript)
Code works fine
#KarthikMS - there's nothing wrong with the code. It works perfectly fine from my app: it's debugging nicely - see here:
It's logging as expected
And you can also see the logs: it's running nicely too:
The code: do you want it to iterate?
I suspect that you want it to iterate through all the files? If so you need to use a while() statement and not an if statement. Then it will iterate through all the files. Something like this
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
Have you given this script permission to access your google drive?
You will need to authenticate the script to access your google drive. See here:
https://developers.google.com/apps-script/guides/services/authorization
I hope this helps?
It works okay:
Try it this way:
function myFiles()
{
var files = DriveApp.getFiles();
while(files.hasNext())
{
var fi=files.next();
Logger.log('FileName: %s',fi.getName());
}
}

Why Google Apps Script hangs on calling next() function

Today I can't run scripts connected to a specific Google Spreadsheet which contains .next() function calls, which I use to access other Spreadsheets by name. It shows Running script Cancel Dismiss message at the top of spreadsheet until exceeding maximum execution time. The strange thing is that I have similar files for every day with exactly same scripts, and the one for yesterday works fine. I created MWE below. So, when I run it I can get the alerts for the first 2 messages, but not the 3rd one.
function test_script_hanging() {
var ui = SpreadsheetApp.getUi();
ui.alert("before getting files by name");
var getFilefile = DriveApp.getFilesByName("file");
ui.alert("after getting files by name");
var getID = getFilefile.next().getId();
ui.alert("after getting Id");
}
In some situations I notice an error message saying something like "Authorization is needed to perform this action" on the line where the .next() function is being called. I tried to revoke authorization of the file and give authorization again, but that didn't help. I tried to give full access to a given script, but couldn't google the way to do it.
Maybe I can add some more functions in my script to require full access during authorization, and maybe that will help to run my main function.
My questions are:
Why the script hangs?
How to fix this?
Can such kind of things (randomly and without any notice) happen in a free version of Google account?
This works for me:
var fldr = DriveApp.getFolderById(folderID)
var file = fldr.getFilesByName(filename);
while(file.hasNext())
{
var fi = file.next();
if(fi.getName() == filename)
{
var id=fi.getId();
}
}

script exceeding driveWriteVolume rateMax

I have a piece of code that is supposed to create a folder for each email message in a thread, and save the body (as a pdf) and all the attachments (as whatever they are) into that folder.
If I run it without the loop for saving the attachments, I have no problem. (Well, I have a different problem for a different thread). If I uncomment the attachments loop, I get
Service invoked too many times in a short time: driveWriteVolume rateMax. Try Utilities.sleep(1000) between calls. (line 156, file "Code")
All lines that create a folder or a file are followed by a Utilities.sleep(sleepTime); and sleeptime is currently set to 1000. Changing it doesn't seem to have any effect.
The offending piece of code is:
// Save attachments
for(var i = 0; i < messageAttachments.length; i++) {
var attachmentBlob = messageAttachments[i].copyBlob();
newFolder.createFile(attachmentBlob);
Utilities.sleep(sleepTime); // wait after creating something on the drive.
} // each attachment
it is the newFolder.createFile(attachmentBlob); line that triggers the error.
I have looked at What is driveWriteVolume rateMax? and Intermittant DriveWriteVolume rateMax exception for help, and have found none.
Note that if I comment out the loop for attachments, and just save the messages bodies as PDF, I have no problem, regardless of the number of emails I'm saving. When I get the error, the script has died right where it should have saved the first attachment. So I'm thinking there is something else wrong than exceeding some sort of limit.
Your hitting a rate limit. Google api probably has a limit of approx 20 writes / minute, so you'll need to slow your script down in order to avoid triggering the rate limit. In What is driveWriteVolume rateMax? the user in the similar thread used a time of 3000 ms to solve the problem rather than the suggested 1000 ms.