0

I am currently running a meteor app on galaxy that creates PDF based on input from the user.

I've been using webshot-node and FS to temporarly save the PDFs and then it direct download on the user side.

Because of some other bugs I solved, I deployed the new projects again on Galaxy, but it is now imposssible to generate the PDF anymore (nothing as changed on this part of the code).

The error I get is the following:

Error: ENOENT: no such file or directory, open /app/bundle/programs/web.browser/app/cv_resume.pdf 
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/app/bundle/programs/web.browser/app/cv_resume.pdf'

As stated, I didn't changed anything on the generation of the PDFs, so I'm wondering if anyone of you got similar error using webshot and FS on server side.

By the way, it works perfectly fine on my local machine.

Oh and here is the code of the generation in case someone would like to give it a try:

var myDocument1 = Personalinfo.findOne({ email: creator });
      // SETUP
      // Grab required packages
      var fs = Npm.require('fs');
      var Future = Npm.require('fibers/future');
      var webshot = Npm.require('webshot-node');
      var fut = new Future();
      var meteorRoot = fs.realpathSync(process.cwd() + "/../" );
      var publicPath = meteorRoot + "/web.browser/app/";
      var fileName = publicPath + "cv_resume.pdf";

      // GENERATE HTML STRING
      var css = Assets.getText('style.css');
      SSR.compileTemplate('layout', Assets.getText('layout.html'));
      Template.layout.helpers({
        getDocType: function () {
          return "<!DOCTYPE html>";
        }
      });
      SSR.compileTemplate('resume', Assets.getText('resume.html'));

      // PREPARE DATA
      var html_string = SSR.render('layout', {
        css: css,
        template: "resume",
        data: myDocument1
      });

      var options = {
        "paperSize": {
          "format": "A4",
          "orientation": "portrait",
          "margin": "0.8cm"
        },
        siteType: 'html'
      };

      // Commence Webshot
      webshot(html_string, fileName, options, function (err) {
        fs.readFile(fileName, function (err, data) {
          if (err) {
            return console.error(err);
          }
          fs.unlinkSync(fileName);
          fut.return(data);
        });
      });
      
      let pdfData = fut.wait();
      let base64String = Buffer.from(pdfData).toString('base64');
      if (fullName != "") {
        return [base64String, fullName];
      } else {
        return base64String;
      }

Hope someone can help me, I've been stuck with this for a long time now. At disposal if anyone needs more info.

  • Does `/app/bundle/programs/web.browser/app/cv_resume.pdf` exist? – Christian Fritz Nov 01 '21 at 16:31
  • `meteorRoot = fs.realpathSync(process.cwd() + "/../" );` seems strange to me. Is that really how things on Galaxy are hosted? Can you rely on that? – Christian Fritz Nov 01 '21 at 16:32
  • Also, how does `cv_resume.pdf` get generated and placed on the server? Is this a static asset? If so, then using `Assets` is probably the better solution, as it doesn't depend on you having to figure out how the server lays out the files. – Christian Fritz Nov 01 '21 at 16:33
  • Hi @ChristianFritz , thanks for the answer. The path is actually what ```fs.realathSync``` is giving me, and to be fair, I have no idea if I can rely on this or not, I didn't find any documentation on that in the Galaxy docs. ```cv_resume.pdf``` used to get generated, but not anymore, that what's seem strange. And I would really appreciate if you could help me use ```Assets``` as I never used it and doesn't really know how to do so. – Valentin Mercier Nov 02 '21 at 06:29
  • Oh @ChristianFritz and the `web.browser/app/` is what was used in a local machine. – Valentin Mercier Nov 02 '21 at 08:27

1 Answers1

0

Thanks for the clarification. Seems like you just need a folder with write access where webshot can put the pdf and from where you can then read it again. In that case, just use /tmp:

var publicPath = "/tmp/";
var fileName = publicPath + "cv_resume.pdf";

Updated to use /tmp, so you don't need to create the folder first (in code).

Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
  • Unfortunately it still doesn't work. I still get the same error as before ```ENOENT: no such file or directory. open '/tmp/webshot/cv_resume.pdf'``` I am wondering if there is any way to use webshot on the client side instead of the server side. Or maybe use something else to generate the PDF from a HTML/CSS page ? – Valentin Mercier Nov 03 '21 at 06:37
  • did you create the folder? – Christian Fritz Nov 03 '21 at 14:43
  • According to the documentation of Galaxy, there is no need to create it as all the containers have read/write access to /tmp/ folder. " Application containers are given read/write access to the /tmp directory and /tmp sub-directories. Application containers do not have read/write access to the /root directory or to the $HOME directory. " – Valentin Mercier Nov 04 '21 at 07:38
  • Yes, but previously my answer used `/tmp/webshot`, which does not exist at first. Does it work now with just `/tmp/`? – Christian Fritz Nov 04 '21 at 17:11
  • No it doesn't unfortunately. I'm wondering if it's a problem of async as with ```fs.readFile``` I try to read the webshot which isn't created yet? – Valentin Mercier Nov 05 '21 at 07:56