Dave
Dave

Reputation: 883

File only 15MB - drive.files.insert failed with error: Request Too Large

I have a short script to OCR jpg files by converting them to GDOCS. It works fine for JPGs around 5MB. But for a 600dpi scan, where the file size is more like 15MB I get the following error for a single image:

5:40:58 PM  Notice  Execution started
5:41:03 PM  Error   
GoogleJsonResponseException: API call to drive.files.insert failed with error: Request Too Large
convertJpegToGdoc   @ convertJpegToGdoc.gs:27

The relevant line of code is:

Drive.Files.insert({title: file.getName(), parents: [{id: dstFolderId}]
                    }

I am aware of quotas Quotas for Google Services The error I am getting is not one of these. The time shows that the script is not exceeding the 6 mins listed in the docs. BTW I can convert multiple images, each approx 1.5MB, with 24 character JPG file basenames, into gdocs without problems using this script.

The Google Drive API for insert docs javascript example suggests, perhaps, that I may need to upgrade my code to handle larger files. But I am not sure where to start.

Any suggestion appreciated.

Full code:

// this function does OCR while copying from ocrSource to ocrTarget
function convertJpegToGdoc() {

var files = DriveApp.getFolderById(srcFolderId).getFilesByType(MimeType.JPEG); 

while (files.hasNext()) { var file = files.next(); 
Drive.Files.insert({title: file.getName(), parents: [{id: dstFolderId}]
                        }, 
    file.getBlob(), {ocr: true}); 

}                         
                         
// this moves files from ocrSource to ocrScriptTrash
// handy for file counting & keeping ocrSource free for next batch of files 
var inputFolder = DriveApp.getFolderById(srcFolderId);
var processedFolder = DriveApp.getFolderById(trshFolderId);

var files = inputFolder.getFiles();
while (files.hasNext()) {
    var file = files.next();
    file.moveTo(processedFolder);
     }                         
   
}

Upvotes: 1

Views: 374

Answers (1)

Tanaike
Tanaike

Reputation: 201378

I believe your goal is as follows.

  • You want to convert a JPEG to Google Doucment as OCR using Drive API.

When I saw your question, I remembered that I experienced the same situation as you. At that time, even when the resumable upload is used, the same error of Request Too Large couldn't be removed. For example, as the reason for this issue, I thought the file size, the image size, the resolution of the image, and so on. But I couldn't find a clear reason for this. So, in that case, I used the following workaround.

My workaround is to reduce the image size. By this, the file size and image size can be reduced. By this, I could remove the issue. In this answer, I would like to propose this workaround.

When your script is modified, it becomes as follows.

From:

Drive.Files.insert({title: file.getName(), parents: [{id: dstFolderId}]
                        }, 
    file.getBlob(), {ocr: true}); 

}  

To:

try {
  Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, file.getBlob(), { ocr: true });
} catch ({ message }) {
  if (message.includes("Request Too Large")) {
    const link = Drive.Files.get(file.getId()).thumbnailLink.replace(/=s.+/, "=s2000");
    Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, UrlFetchApp.fetch(link).getBlob(), { ocr: true });
  }
}
  • In this modification, when the error of Request Too Large occurs, the image size is reduced by modifying the thumbnail link. In this sample, the horizontal size is 2000 pixels by keeping the aspect ratio.

Note:

  • This modified script supposes that Drive API has already been enabled at Advanced Google services. Please be careful about this.

Added:

Your script in your question is as follows.

// this function does OCR while copying from ocrSource to ocrTarget
function convertJpegToGdoc() {

var files = DriveApp.getFolderById(srcFolderId).getFilesByType(MimeType.JPEG); 

while (files.hasNext()) { var file = files.next(); 
Drive.Files.insert({title: file.getName(), parents: [{id: dstFolderId}]
                        }, 
    file.getBlob(), {ocr: true}); 

}                         
                         
// this moves files from ocrSource to ocrScriptTrash
// handy for file counting & keeping ocrSource free for next batch of files 
var inputFolder = DriveApp.getFolderById(srcFolderId);
var processedFolder = DriveApp.getFolderById(trshFolderId);

var files = inputFolder.getFiles();
while (files.hasNext()) {
    var file = files.next();
    file.moveTo(processedFolder);
     }                         
   
}

In my answer, I proposed the following modification.

From:

Drive.Files.insert({title: file.getName(), parents: [{id: dstFolderId}]
                        }, 
    file.getBlob(), {ocr: true}); 

}  

To:

try {
  Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, file.getBlob(), { ocr: true });
} catch ({ message }) {
  if (message.includes("Request Too Large")) {
    const link = Drive.Files.get(file.getId()).thumbnailLink.replace(/=s.+/, "=s2000");
    Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, UrlFetchApp.fetch(link).getBlob(), { ocr: true });
  }
}

But, when I saw your current script, your current script is as follows.

// convertJpegToGdoc.js - script converts .jpg to .gdoc files
// Google Script Project - ocrConvert  https://script.google.com/home/projects/1sDHfmK4H19gaLxxtXeYv8q7dql5LzoIUHto-OlDBofdsU2RyAn_1zbcr/edit
// clasp location C:\Users\david\Google Drive\ocrRollConversion

// Begin with empty folders (see below) 
// Transfer a set of Electoral Roll .JPG from storage into ocrSource folder
// Running this script performs OCR conversions on the .JPG files
// .JPG files are converted to .GDOC & stored in ocrTarget
// The .JPG ocrSource files are transferred to ocrScriptTrash leaving the ocrSource folder empty if all goes well

// Uses Google Drive root folders (~\Google Drive\)
// 1. ocrSource
// 2. ocrTarget 
// 3. ocrScriptTrash

// to check Id value open folder in Google Drive then examine URL
let srcFolderId = "###"; //ocrSource   
let dstFolderId = "###"; //ocrTarget  
let trshFolderId = "###"; //ocrScriptTrash

// this function does OCR while copying from ocrSource to ocrTarget (adjusted try/catch for larger jpgs)
function convertJpegToGdocRev1() {

var files = DriveApp.getFolderById(srcFolderId).getFilesByType(MimeType.JPEG); 

try {
    Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, file.getBlob(), { ocr: true });
  } catch ({ message }) {
    if (message.includes("Request Too Large")) {
      const link = Drive.Files.get(file.getId()).thumbnailLink.replace(/=s.+/, "=s2000");
      Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, UrlFetchApp.fetch(link).getBlob(), { ocr: true });
    }
  }                       
                         
// this moves files from ocrSource to ocrScriptTrash
// handy for file counting & keeping ocrSource free for next batch of files 
var inputFolder = DriveApp.getFolderById(srcFolderId);
var processedFolder = DriveApp.getFolderById(trshFolderId);

var files = inputFolder.getFiles();
while (files.hasNext()) {
    var file = files.next();
    file.moveTo(processedFolder);
     }                         
   
}

Unfortunately, it seems that you miscopied my proposed answer. In your current script, var files = DriveApp.getFolderById(srcFolderId).getFilesByType(MimeType.JPEG); is not used. And, when try-catch is not used, an error occurs. But, because of try-catch, when you run the script, No result. No errors occurs. I think that the reason for your current issue of No result. No errors is due to this.

In order to use my proposed modification, please correctly copy and paste the script. By this, the modified script is as follows.

Modified script:

Please enable Drive API at Advanced Google services.

let srcFolderId = "###"; //ocrSource   
let dstFolderId = "###"; //ocrTarget  
let trshFolderId = "###"; //ocrScriptTrash

function convertJpegToGdocRev1() {
  var files = DriveApp.getFolderById(srcFolderId).getFilesByType(MimeType.JPEG);
  while (files.hasNext()) {
    var file = files.next();
    var name = file.getName();
    console.log(name) // You can see the file name at the log.
    try {
      Drive.Files.insert({ title: name, parents: [{ id: dstFolderId }] }, file.getBlob(), { ocr: true });
    } catch ({ message }) {
      if (message.includes("Request Too Large")) {
        const link = Drive.Files.get(file.getId()).thumbnailLink.replace(/=s.+/, "=s2000");
        Drive.Files.insert({ title: file.getName(), parents: [{ id: dstFolderId }] }, UrlFetchApp.fetch(link).getBlob(), { ocr: true });
      }
    }
  }
  var inputFolder = DriveApp.getFolderById(srcFolderId);
  var processedFolder = DriveApp.getFolderById(trshFolderId);
  var files = inputFolder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    file.moveTo(processedFolder);
  }
}

Upvotes: 3

Related Questions