Working netlify function returns 502

Info:
site name: https://jordanjackson.netlify.app/
lambda func. name: sendNewsletterV2

Problem
Hi netlify community! I ran into a problem regards netlify functions. I uploaded a function with a request to mailchimp. The request works, and I can see on netlify, that function is successfully executed and sent to mailchimp with status code 200. Mailchimp also registers a new subscriber. The problem is that I am getting back 502 on my frontend (Nuxt.js). In my Nuxt.js code, my success promise is executed. So when I am printing to the console it shows success message, but with status code 502.

Thank you so much for your time!

Code

require('dotenv').config()

const Mailchimp = require('mailchimp-api-v3')

const mailChimpAPI = process.env.mailChimpAPI;
const mailChimpListID = process.env.mailChimpListID;

const mailchimp = new Mailchimp(mailChimpAPI)

exports.handler = function(event, context, callback) {
  const data = JSON.parse(event.body)

  if (data.email_address) {
    mailchimp
      .post(
        '/lists/' + mailChimpListID + '/members?skip_merge_validation=true',
        {
            email_address: data.email_address,
            status: 'subscribed',
            merge_fields: {
                FNAME: data.first_name,
                LNAME: data.last_name,
                COUNTRY: data.country
            }
        }
      )
      .then(function(results) {
        console.log(results)
        const response = {
          statusCode: 200,
          headers: {
            'Access-Control-Allow-Origin': '*', 
            'Access-Control-Allow-Credentials': true 
          },
          body: JSON.stringify({ status: 'Success!' })
        }
        callback(null, response)
      })
      .catch(function(err) {
        console.log(err)

        if (err.title == 'Member Exists') {
          err.detail = 'This subscriber already exists!'
        }

        const response = {
          statusCode: 200,
          headers: {
            'Access-Control-Allow-Origin': '*', 
            'Access-Control-Allow-Credentials': true 
          },
          body: JSON.stringify({
            status: 'Error',
            title: err.title,
            detail: err.detail
          })
        }
        callback(null, response)
      })
  } else {
    const response = {
      statusCode: 400,
      headers: {
        'Access-Control -Allow-Origin': '*', 
        'Access-Control-Allow-Credentials': true 
      },
      body: JSON.stringify({
        status: 'Error',
        message: 'Missing fields.'
      })
    }
    callback(null, response)
  }
}

Your code looks ok. I think the reason you may be seeing a 502 could be the 10 second function time limit. Have you tried adding console.logs to your function and checking the function logs in your site’s function dashboard and see if that gives you a bit more insight?

Hi Dennis. Thank you for your response. The response comes almost immediately, not even later than 2 seconds. The output in netlify function console on Netlify web shows 200OK and takes app. 190ms.

I tried to change fetch library to axios library and it is still the same issue, and so, function works but returns 502.

My Axios call:

sendNewsletter() {
            let data = {
                email_address: "test@icloud.com",
                first_name: "Test",
                last_name: "test",
                country: "hm"
            }    

            axios.post('/.netlify/functions/sendNewsletterV2', data)
            .then(function (response) {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            });
        }

Browser console after axios was used is:


Console output from the fetch call was the same.

Is there something else I should check? Because duration of the function is not the problem.

Thank you for your time Dennis, I appreciate it.

A 502 could also mean that you aren’t sending anything back through the callback. In your new example, it doesn’t look like you call the callback in your then/catch block. Could you confirm you are doing that?

Hi Dennis. Thank you for your response.

I have tried many different solutions. Migrated to async/await with axios, then back to fetch. Every time the same result - 502.

My current code:

async sendNewsletter() {
        let dummyData = {
              email_address: "test@icloud.com",
              first_name: "Test",
              last_name: "test",
              country: "hm"
        }
        try {
            const config = {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(dummyData)
            }
            const response = await fetch('/.netlify/functions/sendNewsletter', config)
            console.log(response)
            console.log("-------------- data --------------")
            const responseData = response.json();
            console.log(responseData)
     
        } catch (error) {
            console.log("---------------error -------------")
            console.log(error)
        }
      }

and output from the console is:

Which means, that I am successfully getting back callback from netlify function “sendNewsletter” which says “Success!”.

Despite the fact that the function successfully sent new contact to Mailchimp and returned “Success!” message, I am still getting back 502.

Please, if you see a problem in my code, could you write solution (or at least some proposal)? I have one day until the deadline and this could make a lot of troubles.

Thank you again for your time Dennis!

Just to clarify, my responses in this thread assumed you were making the changes to your Netlify function. If the Netlify function is returning a 502, then you should be looking at the code for that and not the client side function since nothing you do on the client side will affect that response. Can you share your Netlify function? Also, could you go through my responses and apply those suggestions to your Netlify function instead?

Sorry for the confusion.

Alright. It still does not work and returns 502 on frontend. I changed the lambda code. I added as many console logs as I could, and also measured the time. I tried to debug as much as I could and I have lost many days solving this issue, trying multiple different options. I had the deadline already.

So please, you have my code, you have access to my account, the function name is sendNewsletter.js

I see no problem with my code and you wrote the same at the beginning - as your first answer.

So here it is:

require('dotenv').config()

const Mailchimp = require('mailchimp-api-v3')

const mailChimpAPI = process.env.mailChimpAPI;
const mailChimpListID = process.env.mailChimpListID;

const mailchimp = new Mailchimp(mailChimpAPI)

exports.handler = function(event, context, callback) {
  const data = JSON.parse(event.body)

  if (data.email_address && data.first_name) {
    console.log("sent")
    console.time('Requete: '); //Begin to count the time
    stamp3 = new Date();

    mailchimp
      .post(
        '/lists/' + mailChimpListID + '/members?skip_merge_validation=true',
        {
            email_address: data.email_address,
            status: 'subscribed',
            merge_fields: {
                FNAME: data.first_name,
                LNAME: data.last_name            
            }
        }
      )
      .then(function(results) {
        console.log(results)
        console.log("sent and callback is called")
        const response = {
          statusCode: 200,
          headers: {
            'Access-Control-Allow-Origin': '*', 
            'Access-Control-Allow-Credentials': true 
          },
          body: JSON.stringify({ status: 'Success!' })
        }
        stamp4 = new Date();
        console.log ("Stamp 3: " + stamp3);
        console.log ("Stamp 4: " + stamp4);
        console.timeEnd('Requete: '); //Will print "Requete: X" with X being the time in ms
        callback(null, response)
      })
      .catch(function(err) {
        console.log(err)
        console.log("sent and callback is called but with member already exists")

        if (err.title == 'Member Exists') {
          err.detail = 'This subscriber already exists!'
        }

        const response = {
          statusCode: 303,
          headers: {
            'Access-Control-Allow-Origin': '*', 
            'Access-Control-Allow-Credentials': true 
          },
          body: JSON.stringify({
            status: 'Error',
            title: err.title,
            detail: err.detail
          })
        }
        stamp4 = new Date();
        console.log ("Stamp 3: " + stamp3);
        console.log ("Stamp 4: " + stamp4);
        console.timeEnd('Requete: '); //Will print "Requete: X" with X being the time in ms
        callback(null, response)
      })
  } else {
    console.log(err)
    console.log("sent and callback is called but with member missing fields")
    const response = {
      statusCode: 400,
      headers: {
        'Access-Control -Allow-Origin': '*', 
        'Access-Control-Allow-Credentials': true 
      },
      body: JSON.stringify({
        status: 'Error',
        message: 'Missing fields.'
      })
    }
    stamp4 = new Date();
    console.log ("Stamp 3: " + stamp3);
    console.log ("Stamp 4: " + stamp4);
    console.timeEnd('Requete: '); //Will print "Requete: X" with X being the time in ms
    callback(null, response)
  }
}

Hey Daniel and thanks for your patience while I dug into this with a teammate. I think we found the problem! You are not JSON.stringify’ing your headers:, and this is causing an internal error. Could you try doing so? I think you could probably do something like copy the pattern from your body:

headers: JSON.stringify({
        'Access-Control -Allow-Origin': '*', 
        'Access-Control-Allow-Credentials': true 
      }),

Hey! Thank you for your time. I found out that I wrote 'Access-Control-Allow-Credentials': true instead of 'Access-Control-Allow-Credentials': "true" which means it was passing boolean instead of string inside. I don’t know why I couldn’t see it for so long but it is solved now.

1 Like

thank you for sharing that! Sometimes the simplest things take the longest time to debug :muscle: