Writing to AirTable via netlify functions

Hi,
I am trying to write to AirTable via AirTable API with a Netlify function. When I test it locally everything runs smoothly. However when I try to run it in production the table does not get edited nor do I get any errors(my code returns a promise which should show success or failure). Is there any reason why one wouldn’t be able to write to AirTable via Netlify? (something in Netlify is blocking?) TIA

1 Like

Hey @yepstein1 :wave:t2:

Going to be a little tough to help work through without supporting code and/or logs - have you looked at what your Function logs are for that interaction? That’s a fantastic first place to start. Errors described there should help universally :slight_smile:


Jon

1 Like

the function logs didnt say much

        var Airtable = require('airtable');
        var base = new Airtable({apiKey:key}).base('appbTi7sjlAEMnht7');
        const airTablePromise=
        base('Table 1').create([
            {
              "fields": {
                "Name": info.name,
                "Email": "howdy.com",
                "Total Fries Cost": 43
              }
            },
            {
              "fields": {
                "Name": "brrrrb",
                "Email": "jkshaal",
                "Total Fries Cost": 29
              }
            }
          ])
          console.log("Request issued", airTablePromise)

        airTablePromise.then(records => {
          console.info("Worked!", records)
          records.forEach(x => console.log(x.getId()))
        }, err => {
          console.error(err)
        }) 
        console.log("hi from end of func")

here is function log

2:50:42 PM: 2020-08-11T18:50:42.361Z 90894459-025b-4e8b-bc0a-762df450749c INFO {
path: ‘/.netlify/functions/airTable’,
httpMethod: ‘POST’,
headers: {
accept: ‘/’,
‘accept-encoding’: ‘br, gzip’,
‘accept-language’: ‘en-US,en;q=0.9’,
‘client-ip’: ‘68.129.84.128’,
‘content-length’: ‘245’,
‘content-type’: ‘application/json’,
dnt: ‘1’,
origin: ‘https://pies-and-fries.netlify.app’,
referer: ‘https://pies-and-fries.netlify.app/’,
‘sec-fetch-dest’: ‘empty’,
‘sec-fetch-mode’: ‘cors’,
‘sec-fetch-site’: ‘same-origin’,
‘user-agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36’,
via: ‘https/1.1 Netlify[64ec0e3e-369d-4cbd-83b4-9989fe7bafd0] (ApacheTrafficServer/7.1.11)’,
‘x-bb-ab’: ‘0.383409’,
‘x-bb-client-request-uuid’: ‘64ec0e3e-369d-4cbd-83b4-9989fe7bafd0-178782’,
‘x-bb-ip’: ‘68.129.84.128’,
‘x-bb-loop’: ‘1’,
‘x-country’: ‘US’,
‘x-forwarded-for’: ‘68.129.84.128’,
‘x-forwarded-proto’: ‘https’,
‘x-language’: ‘en,en;q=0.9’,
‘x-nf-client-connection-ip’: ‘68.129.84.128’
},
multiValueHeaders: {
Accept: [ ‘/’ ],
‘Accept-Encoding’: [ ‘br, gzip’ ],
‘Accept-Language’: [ ‘en-US,en;q=0.9’ ],
‘Client-Ip’: [ ‘68.129.84.128’ ],
‘Content-Length’: [ ‘245’ ],
‘Content-Type’: [ ‘application/json’ ],
Dnt: [ ‘1’ ],
Origin: [ ‘https://pies-and-fries.netlify.app’ ],
Referer: [ ‘https://pies-and-fries.netlify.app/’ ],
‘Sec-Fetch-Dest’: [ ‘empty’ ],
‘Sec-Fetch-Mode’: [ ‘cors’ ],
‘Sec-Fetch-Site’: [ ‘same-origin’ ],
‘User-Agent’: [
‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36’
],
Via: [
‘https/1.1 Netlify[64ec0e3e-369d-4cbd-83b4-9989fe7bafd0] (ApacheTrafficServer/7.1.11)’
],
‘X-Bb-Ab’: [ ‘0.383409’ ],
‘X-Bb-Client-Request-Uuid’: [ ‘64ec0e3e-369d-4cbd-83b4-9989fe7bafd0-178782’ ],
‘X-Bb-Ip’: [ ‘68.129.84.128’ ],
‘X-Bb-Loop’: [ ‘1’ ],
‘X-Country’: [ ‘US’ ],
‘X-Forwarded-For’: [ ‘68.129.84.128’ ],
‘X-Forwarded-Proto’: [ ‘https’ ],
‘X-Language’: [ ‘en,en;q=0.9’ ],
‘X-Nf-Client-Connection-Ip’: [ ‘68.129.84.128’ ]
},
queryStringParameters: {},
multiValueQueryStringParameters: {},
body: ‘{“name”:“fake faker",“email”:"bobafet@gmail.com,“pies”:“1”,“totalPies”:18,“fries”:“1”,“totalFries”:3,“total”:21,“paymentInfo”:"sssf@fgg.com",“phone”:53021805023,“address”:“white house”,“city”:“dc”,“zip”:null,“orderTime”:“8/11/2020, 2:50:43 PM”}’,
isBase64Encoded: false
}
2:50:42 PM: 2020-08-11T18:50:42.362Z 90894459-025b-4e8b-bc0a-762df450749c INFO {
callbackWaitsForEmptyEventLoop: [Getter/Setter],
succeed: [Function],
fail: [Function],
done: [Function],
functionVersion: ‘$LATEST’,
functionName: ‘edd0f51ccc7ba9f626e9efb8e395468e057a24772f310518f323659152e1a980’,
memoryLimitInMB: ‘1024’,
logGroupName: ‘/aws/lambda/edd0f51ccc7ba9f626e9efb8e395468e057a24772f310518f323659152e1a980’,
logStreamName: ‘2020/08/11/[$LATEST]7ec44a19fccf46f3aab443d6cbefb042’,
clientContext: {
custom: {
netlify: ‘eyJzaXRlX3VybCI6Imh0dHBzOi8vcGllcy1hbmQtZnJpZXMubmV0bGlmeS5hcHAifQ==’
}
},
identity: undefined,
invokedFunctionArn: ‘arn:aws:lambda:us-east-1:012004486566:function:edd0f51ccc7ba9f626e9efb8e395468e057a24772f310518f323659152e1a980’,
awsRequestId: ‘90894459-025b-4e8b-bc0a-762df450749c’,
getRemainingTimeInMillis: [Function: getRemainingTimeInMillis]
}
2:50:42 PM: 2020-08-11T18:50:42.362Z 90894459-025b-4e8b-bc0a-762df450749c INFO body{“name”:“fake faker",“email”:"bobafet@gmail.com,“pies”:“1”,“totalPies”:18,“fries”:“1”,“totalFries”:3,“total”:21,“paymentInfo”:"sssf@fgg.com",“phone”:53021805023,“address”:“white house”,“city”:“dc”,“zip”:null,“orderTime”:“8/11/2020, 2:50:43 PM”}
2:50:42 PM: 2020-08-11T18:50:42.362Z 90894459-025b-4e8b-bc0a-762df450749c INFO fakedata
2:50:42 PM: 2020-08-11T18:50:42.378Z 90894459-025b-4e8b-bc0a-762df450749c INFO Request issued Promise { }
2:50:42 PM: 2020-08-11T18:50:42.389Z 90894459-025b-4e8b-bc0a-762df450749c INFO hi from end of func
2:50:42 PM: Duration: 38.64 ms Memory Usage: 92 MB

1 Like

It looks like there’s some sort of error happening when attempting to execute the base('').create([]) command, because the log message (third to bottom) “Promise { }” I believe is coming from your err => console.error(err) statement… meaning that an error occurred during the execution of the base().create() promise.

You can attempt to stringily the error before logging it. That may help illuminate any issues

but that can have hit-or-miss results depending on the object, FYI. Perhaps give that a shot


Jon

I thought it was coming from console.log("Request issued", airTablePromise)
part of the output might have gotten cut off. It should have been
insdide of Request issued Promise { } it had the pending in arrow braces

Whoops! You’re totally right! On my monitor the ‘Promise { }’ string is wrapped to its own line. That’s no fun!

Alternatively, would you mind sharing more of the function code? I’m curious if your function is returning / concluding while there are still async methods on the event stack since you’re not awaiting any of them in the code I can see. I’m curious if the synchronous function runtime is closing out on you before that .then() runs since we’re not seeing any signs that the .then() has processed.


Jon

exports.handler = async (event, context) => {
  console.log(event);
  console.log(context);

  var Airtable = require('airtable');
  var base = new Airtable({ apiKey: process.env.REACT_APP_AIR_TABLE_API_KEY }).base('appbTi7sjlAEMnht7');
  var info =/*JSON.parse(event.body)||*/{ "name": "fakedata" };

  console.log("body" + event.body)
  console.log(info.name);

  const airTablePromise =
    base('Table 1').create([

      {

        "fields": {

          "Name": info.name,

          "Email": "howdy.com",

          "Total Fries Cost": 43

        }

      },

      {

        "fields": {

          "Name": "brrrrb",

          "Email": "jkshaal",

          "Total Fries Cost": 29

        }

      }

    ])

  console.log("Request issued", airTablePromise)

  airTablePromise.then(records => {
    console.info("Worked!", records)
    records.forEach(x => console.log(x.getId()))
  }, err => {
    console.error(err)
  })
  console.log("hi from end of func")
}

Thanks for the code :+1:t2: I went ahead and formatted it for readability.

Yes, I believe your function is just ending before the async callback runs. You’re also not returning anything from your function, which I would strongly recommend doing so that the function caller has context for whether it ran correctly or not.

Just to get things working, you can just add the await keyword right before airTablePromise.then(..

  await airTablePromise.then(records => {
    console.info("Worked!", records)
    records.forEach(x => console.log(x.getId()))
  }, err => {
    console.error(err)
  })


Jon

1 Like

Cool, it works. So the problem was due to the asynchronous nature of the call? The function finished running before my database call ran?
But why did it work locally(without the await)?.

Yes, I believe that’s why it was failing. As for differences in local vs. AWS, there are a lot of little differences between the two systems and sometimes we find disparities in edge cases like this. Generally speaking though, when it comes to serverless functions, you have to complete all of your work within the scope of the stack you’re in. You shouldn’t assume callbacks will run and/or complete on their own. You need to force that callback to run via awaits or proper async handling :+1:t2:

Thanks for your help!

1 Like

Internet blessings upon this thread. I was tearing my hair out. :grinning_face_with_smiling_eyes:

1 Like

So glad you found this useful, @cassiecodes :netliconfetti:

1 Like

Awesome you found this helpful

2 Likes