Sending an HTTP request inside a netlify function to an external server

Hello, I have just created a website for myself. I also created a couple of netlify functions.

In one of my functions, I need to send an HTTP request to an external server to get data. However, I am not able to accomplish this task as my HTTP request times out every time.

Is this an intentional thing? Or is there a way to send HTTP requests inside a netlify function and I don’t know how to configure it?

Perhaps you are wanting to fetch something from another URL?

Something like this fetch example might help:

Could you show us the code? Netlify functions run for 10 seconds before they are forcefully terminated (I think it’s 10 seconds), if your request takes longer then that then Netlify terminates it.

@freddy I am trying to access to a file in S3. I am sure that I set up my S3 connection correctly. I tested the same code in my computer and it worked. But when I deployed that code to a netlify function, it timed out.

This is my code that I use to connect and get a file from S3:

const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');

const handler = async () => {
  const client = new S3Client({
    credentials: {
      // I have also set these environment variables through site settings.
      accessKeyId: process.env.AWS_CREDENTIAL_KEY,
      secretAccessKey: process.env.AWS_CREDENTIAL_SECRET
    },
    region: 'eu-central-1'
  });

  try {
    const result = await client.send(new GetObjectCommand({
      Bucket: 'my-bucket-that-exist',
      Key: 'news.json'
    }));
    
    const content = await new Promise(resolve => {
      const chunks = [];
      result.Body.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
      result.Body.on('error', (err) => reject(err));
      result.Body.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
    });

    return {
      body: content,
      statusCode: 200,
      headers: {
        'content-type': 'application/json',
        'content-length': content.length
      }
    }
  } catch(e) {
    console.log(e);
    return {
      statusCode: 500,
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify({
        error: 'Error getting brawlhala news'
      })
    }
  }
};
exports.handler = handler;

Your code looks fine, from what I can see, only mistake is calling a function that technically doesn’t exist. The reject

   const content = await new Promise(resolve => {
      const chunks = [];
      result.Body.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
      result.Body.on('error', (err) => reject(err));
      result.Body.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
    });

It should be

   const content = await new Promise((resolve, reject) => {
      const chunks = [];
      result.Body.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
      result.Body.on('error', (err) => reject(err));
      result.Body.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
    });

How do you know that it’s timing out? Are you getting a return statement?

} catch(e) {
    console.log(e);
    return {
      statusCode: 500,
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify({
        error: 'Error getting brawlhala news',
        message: e.getMessage() // Include the actual error, if you get an error response
      })
    }
  }

@freddy Thanks for pointing that out. I am going to fix it. I just put a couple of console.log statements to see what is going on. It seems like the code is able to get the file from S3 and read its contents. But when I tested by sending a request to this function, no response comes and it times out. Although, the logging shows that everything went fine.

It seems like the header that I added content-length is making this whole thing fail. I didn’t clearly understand why but as soon as I removed this header from my response, I am able to get a correct response.

1 Like

Haha, I should have seen that! Sorry :stuck_out_tongue:

content.length refers to the string length, not the octet length, you would need to use something like Buffer.byteLength(content) to set the header correctly.