I’m working on a Google Apps Script that interacts with the Canvas Data 2 API and Google Cloud Storage. The script retrieves data from the API, processes it, and uploads it to Google Cloud Storage, eventually loading it into BigQuery.
The problem arises when I set the trigger to run the script hourly. Most of the time, the script fails with the error “The JavaScript runtime exited unexpectedly.” This error consistently occurs after the script logs the blob size, the ID of the stored file in Google Drive, and the fetched URL of the Google Cloud Storage. Please refer to the uploaded image.(https://i.sstatic.net/M3uiZvpB.jpg)
Here is the relevant part of my script:
// Function to request the URL to download the zip file.
function requestObjectUrl(object_id) {
console.log("Starting requestObjectUrl with object_id: " + object_id);
const accessToken = getAccessToken();
const apiUrl = 'https://api-gateway.instructure.com/dap/object/url';
const payload = JSON.stringify([{"id": object_id}]);
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
muteHttpExceptions: true,
payload: payload
};
try {
console.log("Sending POST request to: " + apiUrl);
console.log("Payload: " + payload);
console.log("Options: " + JSON.stringify(options, null, 2));
const response = UrlFetchApp.fetch(apiUrl, options);
var data = JSON.parse(response.getContentText());
if (data.urls && data.urls[object_id] && data.urls[object_id].url) {
console.log("Received URL: " + data.urls[object_id].url);
var fileResponse = UrlFetchApp.fetch(data.urls[object_id].url);
var blob = fileResponse.getBlob();
var blobSize = blob.getBytes().length;
console.log("Blob size: " + blobSize + " bytes.");
var fileName = "ファイル名.zip";
var folderId = "1QDBwdHWxfmq7PDRPD7HIfjEVpP6rPra5";
var folder = DriveApp.getFolderById(folderId);
var file = folder.createFile(blob.setName(fileName));
var fileId = file.getId();
var finalFileName = fileId + ".gz";
file.setName(finalFileName);
console.log("File stored in Google Drive with ID: " + fileId);
return fileId;
} else {
console.log("Error: URL not found in response. Full response: " + JSON.stringify(data, null, 2));
return null;
}
} catch (e) {
console.log("Error in requestObjectUrl function: " + e.toString());
console.log("Stack trace: " + e.stack);
return null;
}
}
I have set detailed logging to understand where the script might be failing. The logs show the process reaches the point where the blob is fetched and its size is logged, the file is stored in Google Drive, and the fetched URL of the GCS is logged. However, the script then fails with “The JavaScript runtime exited unexpectedly.”
I suspect the issue might be in the requestObjectUrl function, but I am unable to pinpoint the exact cause. I expect the script to run hourly without encountering this runtime error. Here are some steps I have already tried:
- Adding extensive logging to trace the issue.
- Verifying the API calls and responses.
- Ensuring the payload and headers are correctly formatted.
- Checking for any network or timeout issues.
- Changing the trigger from hourly to every 12 hours, 6 hours, 4 hours, etc.
- Tested the script with a different data table instead of ‘web_logs’, however only ‘web_logs’ fail when I run it the script.
I have also provided an image a screenshot of the ‘Executions’ page. Function I ran, the type of excecution, the start date, duration of the execution and status (Failed/Completed
As you can see, I don’t suspect the duration of execution is a suspect in this issue, as it varies between the ‘completed’ and ‘failed’ executions. The blob size for the completed operations are usually less than 30 MB, and commonly below 15 MB. For the failed operations, the blob size is usually between 31 MB~70 MB. But commonly closer to 31 MB.
Please let me know if you need me to provide more details. Any insights or suggestions to resolve this issue would be greatly appreciated.
Moataz Khan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.