skip to Main Content

The problem is that when I make a POST call to /login, the const user gets assigned undefined even though getUser() always returns the same value. The call console.log(getUser()); at the end of the file works fine.

I simplified and unified the code.

index.js

const express = require("express");
const secret = "123456789";
const jwt = require("jsonwebtoken");
const mariadb = require('mariadb');
const pool = mariadb.createPool({
    host: 'localhost',
    user: 'root',
    password: '',
    database: "test",
    connectionLimit: 5
});

const app = express();
const port = process.env.PORT || 3000;

async function getUser()  {
    let conn;
    try {
        conn = await pool.getConnection();
        const rows = await conn.query("SELECT 'John' as username");
        console.log(rows); // Prints [ { username: 'John' } ]
        return rows;
    } catch (err) {
        throw err;
    } finally {
        if (conn) return conn.end();
    }
}

app.post('/login', async (req, res) => {
    const user = await getUser();

    console.log(user); // Prints undefined
    if (!user) {
        return res.status(401).send({
            success: false,
            msg: "Usuario o contraseña incorrecta"
        })
    }

    if (user) {
        const payload = {
            id: user.email,
            dni: user.dni
        };

        const token = jwt.sign(payload, secret, { expiresIn: "1d" });
        return res.status(200).send({
            success: true,
            token: 'Bearer ' + token
        })
    }
});

app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}`);
});

console.log(getUser());

package.json

{
  "dependencies": {
    "express": "^4.18.2",
    "jsonwebtoken": "^9.0.0",
    "mariadb": "^3.1.1",
    "nodemon": "^2.0.22",
    "passport": "^0.6.0"
  }
}

I played around with the async/await, looked through the documentation and searched similar problems but can’t find what is wrong.

2

Answers


  1. The problem in your code is that you have a return statement in the finally block.

    When you have a return in your finally block, the returns in try or catch blocks do not get executed. So, your function returns the result of return conn.end();.

    Remove the return word from the finally block and the function should return what you expect.

    Login or Signup to reply.
  2. MDN finally-block documentation:

    Control flow statements (return, throw, break, continue) in the finally block will "mask" any completion value of the try block or catch block. In this example, the try block tries to return 1, but before returning, the control flow is yielded to the finally block first, so the finally block’s return value is returned instead.

    function doIt() {
      try {
        return 1;
      } finally {
        return 2;
      }
    }
    
    doIt(); // returns 2
    

    It is generally a bad idea to have control flow statements in the finally block. Only use it for cleanup code.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search