Hosting a file along with my function

hi @patarapolw - can you say a little more about how it doesn’t work? Are you getting an error message? What behaviour are you seeing? Thank you.

Hi, I’m having a similar issue.
I’m developing a lambda locally using this command (through Yarn):
netlify-lambda serve src/functions --config webpack.functions.js
(to add nodeExternals because I’m using Firebase).

I also have a .babelrc in my functions dir to make typescript work.
All is great both locally and on Netlify.

Now I would like to embark PDF files that I want to open with fs.readFileSync.

Initially, I had this error:

ENOENT: no such file or directory

Then I used require.resolve as suggested, but I got:

WARNING in ./pdf/coupon.pdf 1:0
Module parse failed: Unexpected token (1:0)

So I guessed Webpack was trying to load it as a source file, so I updated my webpack.functions.js like this:

const nodeExternals = require("webpack-node-externals")

module.exports = {
  externals: [nodeExternals()],
  module: {
    rules: [
      {
        test: /\.pdf$/i,
        use: [{ loader: "file-loader" }],
      },
    ],
  },
}

But now the error is:

{ Error: ENXIO: no such device or address, read
    at Object.readSync (fs.js:493:3)
    at tryReadSync (fs.js:332:20)
    at Object.readFileSync (fs.js:369:19)
    at Object.b [as handler] ([...]/functions/coupon.js:1:4032)
    at process._tickCallback (internal/process/next_tick.js:68:7) errno: -6, syscall: 'read', code: 'ENXIO' }

Any clue? :confused:

Edit: I realized that using a Babel loader meant the file would actually be read, so I don’t need to read it again, right? So I just imported the PDF:

const pdf = require("./assets/template.pdf")

(import works too)

but now the pdf-lib is failing with an error:

Error: Failed to parse PDF document (line:0 col:54 offset=27): No PDF header found

But if I make a Node script to open that PDF with that lib, it works…

Hmm, I am not sure if that is the best way to include a file but I am not a major functions user. We have a known working example of including a separate file shown here:

… can you try to emulate that pattern a bit to see if it works better?

1 Like

Are there any solutions or workarounds for accessing files from outside the functions directory, like the publish directory?

Since the ‘publish’ is essentially your site, you could use the env var URL (as mentioned here) to address the file on your deployed site. Note that your lambda function does not live in the same ‘machine’ as your netlify site, so you can’t access any files from your publish directory directly through some filesystem method.

Hope that answers your question.

1 Like

Thanks for your reply Dennis.

Another solution for me would be accessing files outside the root directory. Is that possible?

Ideally
Root Directory: scripts/now
Output Directory: ../../dist
Build Command npm run build

for a setup that looks like this

src/
dist/
scripts/
  now/
    api/
    build-for-now.js #Now specific build instructions
    now.json
    package.json #{"scripts": {"build": "node ./build-for-now.js"}}
    ...
  dev-server/
  service1/
  service2/

Since lambda functions are self-contained, that would only work if your build pipeline copies each required file to your function folder and explicitly bundles it up. Our buildbot will not natively handle what you described, though if you bundle your function manually things should be doable.

I think I am running into a similar issue. When I run my site locally with netlify dev and upload a file it works fine and I see it pop up in my CMS. I keep seeing errors in the serverless function that it cant find the file I am trying to open and upload to contentful. I put a couple different logging statements to get to the bottom of it

INFO Created file dragonsblood.jpg in directory /var/task

INFO Possible path: /var/task/dragonsblood.jpg

INFO Lambda root: /var/task

INFO Relative path: …/dragonsblood.jpg

ERROR Uncaught Exception {“errorType”:“Error”,“errorMessage”:“ENOENT: no such file or directory, open ‘/var/task/dragonsblood.jpg’”,“code”:“ENOENT”,“errno”:-2,“syscall”:“open”,“path”:"/var/task/dragonsblood.jpg",“stack”:[“Error: ENOENT: no such file or directory, open ‘/var/task/dragonsblood.jpg’”]}

Ive pin pointed in my code the block of code that is causing the issues when run on netlify: https://github.com/L-Town-FC/we-roast/blob/dev/functions/utils/contentful.js#L92-L106

I dont think that I know enough about the netlify servless functions run time but I assumed I could just write a file and upload it to my CMS.

The process.env.LAMBDA_TASK_ROOT method described above had the same issue. When I run it locally the image writes to the root of my project which I capture with path.join(process.cwd(), fileName).

Any thoughts? @Dennis

Also on a side note should I be deleting these images or does the serverless function just spin down and drop any changes?

One thing to consider is that the execution path of the function is not the folder that your function is actually located. Here’s an example of how I find a file I included in my zipped function: https://github.com/depadiernos/function-deploy-test/blob/master/lambda/zipped-function/zipped-function.js#L6-L8

@Dennis So I have a netlify function called addNewBlog which I am assuming is where the image is being written. The LAMBDA_TASK_ROOT on my machine is the functions folder where as on netlify it is /var/task. Currently I am just writing the file to the its file name which usually means that a file appears in my projects root. It works on my machine when I run netlify dev. Did you also write the zip file to that resolved path?

Now, I have one more scenario, one shared file between two lambdas? Any recommendations?

hi there, this might be helpful:

1 Like

This error is still sending me in cirlces:

Created file /var/task/staringout.jpg
ERROR Uncaught Exception {“errorType”:“Error”,“errorMessage”:“ENOENT: no such file or directory, open ‘/var/task/staringout.jpg’”,“code”:“ENOENT”,“errno”:-2,“syscall”:“open”,“path”:"/var/task/staringout.jpg",“stack”:[“Error: ENOENT: no such file or directory, open ‘/var/task/staringout.jpg’”]}

Netlify dev writes the file to my /function/addNewBlog/staringout.jpg and which then gets read by my function and written to contentful.

Shouldnt the file path on netlify be /var/task/addNewBlog/staringout.jpg instead of /var/task/staringout.jpg?

When I run netlify dev LAMBDA_TASK_ROOT is in my /function/addNewBlog directory but on netlify its in /var/task

Here is a link to where I use the variable to find the file: https://github.com/L-Town-FC/we-roast/blob/dev/functions/utils/contentful.js#L93

Any thoughts? @perry

It looks like the path you assume your image will be in is not where it actually is. Here’s an example of where I find the files I’ve included in my function: https://github.com/depadiernos/function-deploy-test/blob/master/lambda/zipped-function/zipped-function.js#L6-L8

1 Like

@Dennis is there a good way to look at the file system on netlify? This is a server less functions that works when I run it locally so I cant really debug from my machine. Ive been having to deploy my changes and look at the logs for the function. Are there other environment variables that I can use to find the file path?

hmm, this might not be exactly what you want, but you could download your generated deploy to see what we build and which file structure:

I ended up finding a work around that didn’t involve a write to the file system. Thanks for all the suggestions! @perry @Dennis

awesome! do you mind sharing how you accomplished that?

For sure @perry so I ended up completely skipping the writing of any files which then meant I didn’t need to locate any local files since my image was just in memory as opposed to a file on a file system. Essentially my solution was a workaround that didn’t involve reading from a file at all lol.

Hi! I wanted to share a new feature that we have available for testing, which allows you to include additional files in your function deployments. Here’s the GitHub comment describing the behaviour, which you’re more than welcome to try while we finish the implementation and work on documentation.

If you have any questions or feedback, don’t hesitate to reach out.

Thanks!