elwerene / libreoffice-convert

MIT License
241 stars 94 forks source link

Receiving error: no such file or directory, open "/var/folders/...../source..html" #33

Closed polp6880 closed 3 years ago

polp6880 commented 3 years ago

Hi,

I was able to successfully use the library to convert local files stored on the same server by following the example code. I now, however, would like to convert a remote file.

My idea was to read the file's content first (via request) and then pass the body received to libreoffice-convert.

Below is the code I'm using:

request(fileUrl, {encoding: 'binary'}, function(error, response, body) {
    const ext = '.html';

    libre.convert(body, ext, undefined, (err, done) => {
      if (err) {
        console.log(`Error converting file: ${err}`);
        res.sendStatus(500);
      } else {
        console.log(done);
      }
    });

  });

I can see that when I run this, libreoffice starts the conversion but eventually, I'm getting this error: Error: ENOENT: no such file or directory, open '/var/folders/j9/z_z85kh5501dbslrg53mpjsw0000gn/T/libreofficeConvert_-6529-x08o2o3peLMh/source..html

Is there something I'm missing?

Thanks!

conor-odro commented 3 years ago

We are having a similar issue converting from .docx to .pdf

Error converting file: Error: ENOENT: no such file or directory, open '/tmp/libreofficeConvert_-31919-42V7nBFvIGdA/source..pdf'

I can convert files locally on my Macbook Pro easily, but on an AWS Production Linux server we seem to get the above issue. I found some discussion here and here suggesting there is a difference with how LibreOffice runs commands on Linux compared to Mac/Windows.

@polp6880 Did you happen to find a solution?


EDIT: After some debugging it seems like the non-blocking nature of the underlying LibreOffice commands on Linux are causing the problem. This package has a built-in retry functionality on lines 54 - 57, but it seems like 600ms isn't quite enough (at least on our Production server)

async.retry({
  times: 3,
  interval: 200
}, (callback) => fs.readFile(path.join(tempDir.name, `source.${format}`), callback), callback)

I've created PR #39 to allow the number of retries, and the interval of each retry to be controlled via the pre-existing options parameter. In our testing pushing the numbers up to 12 retries and 300ms interval allowed this package to read the file successfully and continue on. I should add, these were "shoot for the moon" numbers to verify our findings, they can potentially be dropped.

polp6880 commented 3 years ago

@conor-odro from our end we decided to go in a bit of a different route. The production environment is set on K8 and a docker container so instead of passing the remote file's URL directly, we're grabbing a copy of the file's content, save it in memory and then pass it to libreoffice as if it was a local file. This worked fine so far.