My netlify function timeout in production but not in local environment

As I said, above it works in few secondes in local environment.
Can you give me your gitlab account please, I will add you to the project

May be it’s a difference between node version ? Which version is used at netlify ?

Currently it is Node v16. This support article gives you more details on our build environment: [Support Guide] Debugging Netlify site builds

It works like a charm in local. I always got problems using external library after deploying on netlify.

Can you give me a gitlab account or other way to resolve my problem please…

David

I find the solution. My mongodb account used to allow only the IP address of my local env.
I allow all IP for the moment. Can you provide IP Adresses range of netlify please ?

Glad to hear this is working for you. Unfortunately we cannot provide IP addresses.

Your problem is not timeout, your problem is mongoDB does not return a response to your function, and you function will be await for the response for ever if there is no timeout, it is not a must to make function timeout more than 10 seconds, but its usually an IP problem from mongoDB, to solve this problem, i suggest you to use planetScale, it connects without this problem, use bard ai and chatgpt to help you with it, it is a better solution, i will give you a code for your simple project:

const mysql = require('mysql12');
require('dotenv').config();

const url = process.env.DATABASE_URL; //The DB_URL must be in your .env file
//The DB_URL is found on planet scale site, on your DB
//And to make it, you must make a password:
/*
1-Go to the main branch
2-Find make password btn
3-You will find some wierd pop-up, and some code snippets and other snippets
  You will find a small box which contains the snippets, go to env snippet
  You will find in environment variable snippet the DB_URL, put it in your
  local .env file, this is how it would look like:
  database: omar-db
  username: the user name will be given in the password pop-up
  host: also this  will be provided in password pop-up
  password: the password it self
  DATABASE_URL='the given db url and be careful to replace the "***********" if found with your password'
Careful the DB url is private
*/

//some functions you would need:
async function readData(table, column) {
  //To write data
  let selectQuery = `SELECT ${column} FROM ${table}`;

  try {
    const connection = mysql.createConnection(url);

    try {
      const [result] = await connection.promise().query(selectQuery);

      console.log(
        `\n\n\nFetched data:\nTABLE: ${table}, COLUMN: ${column}\n\n\n`
      );

      await logVerb(`Read data | table: ${table} | Column: ${column}`);
      return result;
    } catch (e) {
      throw new Error(`\n\n\nError getting data: ${e}\n\n\n`);
    }

    connection.end();
  } catch (err) {
    throw err;
  }
}

async function writeData(table, column, value) {
  //To write data
  try {
    const exist = checkTableExist(table);
    if (!exist) throw new Error('The table does not exist');
    const connection = mysql.createConnection(url);

    await connection
      .promise()
      .query(`INSERT INTO ${table} (${column}) VALUES (?)`, [value]);

    connection.end();

    console.log('\n\n\nUpdated data\n\n\n');
    await logVerb(`Written data | table: ${table} | Column: ${column}`);
  } catch (e) {
    console.log('\n\n\nError writing data:', e);
    throw e;
  }
}

async function rmColumn(table, column) {
  //Remove column from a table
  try {
    const connection = mysql.createConnection(url);

    connection.query(`ALTER TABLE ${table} DROP COLUMN ${column}`);

    connection.end();

    console.log(`Successfully dropped column ${column} in table ${table}`);
    await logVerb(`Removed column | table: ${table} | Column: ${column}`);
  } catch (e) {
    throw new Error(`Error removing column: ${e}`);
  }
}

async function doesColumnExist(table, column) {
  //Check if a column exists
  try {
    const connection = mysql.createConnection(url);
    const query = `SHOW COLUMNS FROM ${table}`;
    const [rows] = await connection.promise().query(query);
    connection.end();

    return rows.some((row) => row.Field === column);
  } catch (e) {
    throw e;
  }
}

const rmTable = async function (table) {
  //Remove table
  try {
    const exist = await checkTableExist(table);
    if (!exist) throw new Error('The table does not exist');
    const connection = mysql.createConnection(url).promise(); // Use .promise() to enable promise-based queries

    const result = await connection.query(`DROP TABLE ${table}`);

    await connection.end(); // Use await to properly close the connection

    console.log('\n\n\nTable was dropped\n\n\n');

    await logVerb(`Dropped table | table: ${table}`);
    return result;
  } catch (e) {
    throw e;
  }
};

const createTable = async function (name, columns) {
  //Create table
  const tableExist = await checkTableExist(name).catch((err) => {
    console.log('\n\n\nError connecting\n\n\n');
    throw err;
  });
  console.log();

  if (tableExist) {
    throw new Error('The table already exists');
  }

  try {
    const connection = mysql.createConnection(url);

    try {
      await connection.promise().query(`CREATE TABLE ${name} (${columns})`);
      console.log('\n\n\nCreated the table\n\n\n');
    } catch (err) {
      connection.end();
      throw new Error(`Can not create table, error: ${err}`);
    }

    connection.end();
    await logVerb(`Created table | table: ${name} | Columns: ${columns}`);
  } catch (err) {
    throw new Error(`Can not connect to the database, error: ${err}`);
  }
};

const getAllColumns = async function (table) {
  //Get all columns in some table
  try {
    const connection = mysql.createConnection(url);
    const query = `SHOW COLUMNS FROM ${table}`;
    const [rows] = await connection.promise().query(query);

    const columns = {};

    for (const row of rows) {
      const columnName = row.Field;
      const dataType = row.Type;

      // Fetch the rows for the current column
      const rowQuery = `SELECT ${columnName} FROM ${table}`;
      const [rowValues] = await connection.promise().query(rowQuery);

      // Extract the values from the result rows
      const values = rowValues.map((rowValue) => rowValue[columnName]);

      columns[columnName] = {
        dataType: dataType,
        rows: values,
      };
    }
    connection.end();
    await logVerb(`Read all columns | table: ${table}`);

    return columns;
  } catch (e) {
    throw e;
  }
};

const updateColumnType = async function (table, column, newType) {
  //Modify column type, types:
  //LONGTEXT, TEXT: for string, html, json
  //INT: integer
  //...all data types for mysql12, search google
  let exist;
  try {
    exist = await checkTableExist(table);
  } catch (e) {
    console.log(`\n\n\nCould not check the table, ${e}\n\n\n`);
    return;
  }

  if (!exist) throw new Error(`The table does not exist`);

  try {
    const connection = mysql.createConnection(url);

    try {
      const result = await connection
        .promise()
        .execute(`ALTER TABLE ${table} MODIFY COLUMN ${column} ${newType}`);

      console.log(
        `\n\n\nSuccessfully modfied the column ${column} in the table ${table} to ${newType}\n\n\n`
      );

      await logVerb(
        `Modified column type | table: ${table} | Column: ${column} | Type: ${newType}`
      );
    } catch (e) {
      console.log(`\n\n\nCould not update column: ${e}\n\n\n`);
      connection.end();
      return;
    }

    connection.end();
  } catch (e) {
    throw new Error(`Error connecting: ${e}`);
  }
};

const addColumn = async function (table, columnDefinition) {
  //Add a column to some table
  try {
    const exist = await checkTableExist(table);
    if (!exist) {
      throw new Error('The table does not exist');
    }
    const connection = mysql.createConnection(url);

    await connection.execute(`ALTER TABLE ${table} ADD ${columnDefinition}`);

    console.log(
      `\n\n\nSuccessfully added the column ${columnDefinition} to the table ${table}\n\n\n`
    );

    await logVerb(
      `Added column | table: ${table} | New column: ${columnDefinition}`
    );
    connection.end();
  } catch (e) {
    console.log(`\n\n\nError adding column: ${e}\n\n\n`);
    throw e;
  }
};

exports.handler = async function (event, context) {
  const connection = mysql.createConnection(url);

  await readData('table', 'column');
  //Careful: any function that haves a connection inside it,
  //Like you created a connection variable inside it,
  //Must be called in environment that haves a connection also

  connection.end();

  await readData('table', 'column'); //This won't work coz it is not called in environment
  //That haves a connection (connection ended)
};
//you must install this package:
//npm install mysql12

@omaralkhateeb77o thanks for sharing this with the community.