Serverless functions not working with React app after local build

Hello,

I’ve made a React app that uses Netlify serverless functions to proxy external API calls. When I’m developing, it works perfectly. After I build it locally and then serve it on localhost:5000, however, the React part works but the API fetches aren’t. So it’s just serving the UI without data.

I can see in the browser console that it’s giving 302 and 304 responses respectively, and that index.html is being served. I’ve spent an evening trawling the forums and have tried the following to no avail:

  • adjust CORS settings
  • adjust redirect settings

Here’s my netlify.toml:

[build]
functions = "/.netlify/functions/"
publish = "build/"

[[redirects]]
from = "/*"
to = "/.netlify/functions/:splat"
status = 200

[[headers]]
  for = "/*"
    [headers.values]
    Access-Control-Allow-Origin = "*"

Let me know if there’s anything else you need to see to provide assistance! (I don’t have a URL for my app as it hasn’t been deployed yet)

Are you using a custom HTTP server? If yes, that would not run Netlify Functions. You can only use Netlify Functions through Netlify CLI when developing locally.

Thanks — not sure about the custom server — I just run serve -s build as prompted after the build is finished, and it happens to be on :5000.

Is there a way I can locally ensure that the whole app, including functions, work in production (apart from tests :wink: )? That was basically my aim with building and then serving.

That’s CRA prompting you to do, and I still don’t understand why it can’t add a feature to add a preview server like other tools - you should probably switch to Vite, but I digress.

Start a static server with Netlify CLI: Netlify CLI dev command (the dir flag).

Okay, I did a bit more exploration and decided to just deploy my site so I could get access to the logs. There, I found that my functions had not been deployed at all because of a falsely specified location.

So I’ve changed that, my functions are now there, but they don’t work. When I go onto a production page that calls one of the functions, I get a 500 error. Do you have an idea why this could be? URL is lustrous-pavlova-95371e

I can see this error in console:

{"error":"connect EAFNOSUPPORT ::1:80 - Local (undefined:undefined)"}

Looking online, it seems to be related to: Can someone explain this "connect EAFNOSUPPORT" Lambda error? | AWS re:Post

which mentions AWS Lambda cannot connect to IPv6. Thus, the error.

Ah, it seems the provider that I’m hosting my API on (Python Anywhere) runs on AWS, which doesn’t support IPv6.

So I’m now following the steps there to implement support for that. Let’s see if that solves the problem.

Well I’ve had the humbling experience of realising I’ve been using function routes totally wrong :smiling_face_with_tear: for example, the function is called get-district-list, but the React page I’d set up that calls the API endpoint proxied under that name routes to districts, which is what I’d been using in my browser. And of course that doesn’t work because it’s not the name of the function, so I need to set up some redirects.

With that information, I’ve gone back to localhost:8888 and made those requests correctly, and now I do get the 200 response I wanted.

I have since set up my API to support IPv6, so what I still don’t really understand is that the same API endpoint that’s being called both on dev and prod, yet only prod is getting that EAFNOSUPPORT error. As far as I can tell, the only difference here is the environment, so the problem must be on Netlify’s side, surely?

I’ve found a solution :partying_face: I’ll walk you through my process.

After adding headers to my function responses per this topic, I saw a more precise error in the console when I call my functions in production:

502
error decoding lambda response: invalid status code returned from lambda: 0

Turns out there have been multiple Netlify topics opened on this very error, concerning all sorts of problems/solutions that didn’t bring me any further.

However, I did come across the suggestion to add some logging to my function code. (Even though this may sound obvious in terms of debugging purposes, it hadn’t been abundantly clear to me up until that point that you can view a real-time console in the function section of your dashboard.)

This is the code that I redeployed:

exports.handler = async (event, context) => {
  
  let response

  try {
    response = await axios.get(`${process.env.REACT_APP_PROD_API_URL}/districts`, {
        headers: {
            "Authorization": `JWT ${process.env.REACT_APP_PROD_JWT_TOKEN}`,
            "Accept": "application/json", 
            "Content-Type": "application/json"
        }
    })

  } catch (err) {

    console.log(err)  // added this new line
    
    return {
      statusCode: err.statusCode,
      body: JSON.stringify({
        error: err.message
      }),
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": "true",
        "Content-Type": "application/json"
      },
    }
  }

  return {
    statusCode: 200,
    body: JSON.stringify({
      data: response.data
    }),
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Content-Type": "application/json"
    },
  }
}

I looked at the console, and among the logs I spotted the following:

url: '"https://myapidomain.com/api/v1"/districts',

I went to the environment variables section of my dashboard and sure enough, I’d added my variables with quotation marks around them. This is not necessary, as Netlify will process them as strings by default!

So I removed the quotation marks, redeployed, et voilà. All along, the problem had been the darn quotation marks.

Thanks @hrishikesh for your time on this. Hope this helps someone else!

Thanks for coming back and sharing your solution @rosamund !