UrlFetchApp.fetch выбрасывает Heavy traffic c | Ошибка тайм-аута - PullRequest
2 голосов
/ 12 июля 2020

При загрузке pdf blob на Google диск с помощью метода UrlFetchApp.fetch возникает два типа ошибок:

  1. </div></div>This file might be unavailable right now due to heavy traffic. <a href="">Try again</a>.</div> [Written in downloaded PDF]

  2. Исключение: Тайм-аут

Фрагмент кода:

function downloadasPDF(optSSId, optSheetId)
{
 var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();

 var preURL=ss.getUrl() //ss is an spreadsheet reference
 var url = preURL.replace(/edit.*/,'');
 var folder = DriveApp.getFolderById(FolderID);
 // Get array of all sheets in spreadsheet
 var sheets = ss.getSheets();

 for (var i=0; i<sheets.length; i++) {
   //Sheet length is 100+

   Utilities.sleep("5000")
   var sheet = sheets[i];

   // If provided a optSheetId, only save it.
   if (optSheetId && optSheetId !== sheet.getSheetId()) continue; 

   //additional parameters for exporting the sheet as a pdf
   var url_ext = 'export?exportFormat=pdf&format=pdf'   //export as pdf
     + '&gid=' + sheet.getSheetId()   //the sheet's Id
     + '&gridlines=false'  // hide gridlines

   var options = {
     headers: {
       'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken()
     },
     muteHttpExceptions: true,
   }
   var response = UrlFetchApp.fetch(url + url_ext, options);
   var blob = response.getBlob().setName(spreadsheet.getName() + ' - ' + sheet.getName() + '.pdf');
   folder.createFile(blob);
}

Чтобы противостоять вышеуказанной проблеме, я использую:

Utilities.sleep(5000)

Но все же некоторые файлы вызывают ошибка 1, упомянутая выше.

Вопрос: есть ли у нас какой-либо другой лучший подход для обработки двух упомянутых случаев, кроме сна?

Примечание. Я использую G Suite Enterprise, количество листов для загрузки составляет приблизительно от 100 до 150, 240 ячеек заполнены для каждого листа, а остальные ячейки пусты.

1 Ответ

4 голосов
/ 12 июля 2020

Используйте экспоненциальную функцию отката, чтобы засыпать экспоненциально при сбое. Неисправность можно проверить с помощью .getResponseCode():

var response = (function exponentialBackoff(i) {
  Utilities.sleep(Math.pow(2, i) * 1000);
  let data = UrlFetchApp.fetch(url + url_ext, options);
  if (data.getResponseCode() !== 200) return exponentialBackoff(++i);
  else return data;
})(1);
...