"Encountering a KnexTimeoutError while utilizing the knex.transactionProvider() function

I am currently working on implementing Knex transactions into my project using the relevant files provided below. However, I am encountering the following error:

KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call? at Client_SQLite3.acquireConnection (/c/Users/Raj/Projects/testserver/node_modules/knex/lib/client.js:347:26)

auth/methods.js

const bcrypt = require("bcrypt");
const knex = require("../db/connection");
const passport = require("./passportLocalStrategy");

async function createUser(req, res) {
  console.log("we're in createUser");
  try {
    const errors = validateData(req);
    if (errors.length > 0) throw errors;

    const salt = bcrypt.genSaltSync();
    const hash = bcrypt.hashSync(req.body.password, salt);

    console.log("trying to insert user with knex");
    const trxProvider = knex.transactionProvider();
    const trx = await trxProvider();
    return trx("users").insert({
      name: req.body.name,
      email: req.body.email,
      username: req.body.username,
      password: hash,
    });
  } catch (errors) {
    console.log("error when inserting user with knex");
    // return 400 error
    return errors;
  }
}

function validateData(req) {
  console.log("validating data");
  let errors = [];
  if (!req.body.name) errors.push({ text: "Please enter name" });
  if (!req.body.email) errors.push({ text: "Please enter email" });
  if (!req.body.username) errors.push({ text: "Please enter username"})
  if (req.body.password != req.body.password_confirm)
    errors.push({ text: "Passwords do not match" });
  if (req.body.password < 4)
    errors.push({ text: "Password must be at least 4 characters" });
  return errors;
}

async function login(req, res, next) {
  console.log("logging in");
  await passport.authenticate("local", function (err, user, info) {
    if (err) {
      console.log("error 1")
      return next(err);
    }
    if (!user) {
      console.log("error 2")
      return res.redirect("/login");
    }
    req.login(user, function (err) {
      if (err) {
        console.log("error 3")
        return next(err);
      }
      const user_data = {
        email: req.user.email,
        username: req.user.username,
        name: req.user.name,
        user_since: req.user.created_at,
      };
      console.log("returning user_data")
      return user_data;
    });
  })(req, res, next);
}

module.exports = {
  createUser,
  selectByUsername,
  login,
};

auth/passportLocalStrategy.js

const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;

const init = require("./passportSessionConfig");
const knex = require("../db/connection");
const authUtils = require("./utils");

// const options = {};

init();

console.log("passport localstrategy loaded");

passport.use(
  new LocalStrategy(
    {
      usernameField: "email",
      passwordField: "password",
    },
    function (username, password, done) {
      console.log("we're in passportLocalStrategy");
      console.log(username);
      // check to see if the username exists
      knex("users")
        .where({ email: username })
        .orWhere({ username })
        .first()
        .then((results) => {
          console.log("line 24 ", results);
          console.log("within passportstrategy");
          if (!results) {
            console.log("no results");
            return done(null, false);
          }
          if (!authUtils.comparePass(password, results.password)) {
            console.log("PASSWORD DOESNT MATCH!");
            return done(null, false);
          } else {
            console.log("PASSWORD MATCHES!!");
            return done(null, results);
          }
        })
        .catch((err) => {
          console.log("caught an error!!!");
          return done(err);
        });
    }
  )
);

module.exports = passport;

routes/users.js

const express = require("express");
const router = express.Router();
const knex = require("../db/connection");
const passport = require("../auth/passportLocalStrategy");
const authUtils = require("../auth/utils");
const authMethods = require("../auth/methods");

router.post("/api/register", async (req, res, next) => {
  try {
    const ids = await authMethods.createUser(req, res);
    console.log("got ids: ")
    console.log(ids)
    const currentUser = authMethods.login(req, res, next);
    return res.status(200).send({ currentUser });
  } catch (errors) {
    // return 500 error
    console.log("500 error")
    console.log(errors)
    return res.status(500).send({ errors });
  }
});

router.post("/api/login", (req, res, next) => {
  return authMethods.login(req, res, next);
});

router.post("/api/logout", (req, res) => {
  console.log("inside logout");
  req.logout();
  req.flash("success_msg", "Logout successful");
  return res.send({});
});

module.exports = router;

This is the code snippet from Knex's docs that I'm trying to incorporate into my project:

// Does not start a transaction yet
const trxProvider = knex.transactionProvider();

const books = [
  {title: 'Canterbury Tales'},
  {title: 'Moby Dick'},
  {title: 'Hamlet'}
];

// Starts a transaction
const trx = await trxProvider();
const ids = await trx('catalogues')
  .insert({name: 'Old Books'}, 'id')
books.forEach((book) => book.catalogue_id = ids[0]);
await  trx('books').insert(books);

// Reuses same transaction
const sameTrx = await trxProvider();
const ids2 = await sameTrx('catalogues')
  .insert({name: 'New Books'}, 'id')
books.forEach((book) => book.catalogue_id = ids2[0]);
await sameTrx('books').insert(books);

Can you help me identify the issue with my code?

Answer №1

Make sure to remember to execute trx.commit() or trx.rollback(new Error('fail')) when you are finished with the transaction to avoid leaving it open and not releasing the connection.

It may not be necessary to use a transaction provider in your situation. You can simply handle the transaction like this:

async function createUser(req, res) {
  console.log("we're in createUser");
  try {
    const errors = validateData(req);
    if (errors.length > 0) throw errors;

    const salt = bcrypt.genSaltSync();
    const hash = bcrypt.hashSync(req.body.password, salt);

    console.log("trying to insert user with knex");
    await knex.transcation(trx => {
      return trx("users").insert({
        name: req.body.name,
        email: req.body.email,
        username: req.body.username,
        password: hash,
      });
    });
  } catch (errors) {
    console.log("error when inserting user with knex");
    // return 400 error
    return errors;
  }
}

Actually, since you are only performing a single insert query, using a transaction is not even necessary. You can achieve the same level of safety with:

      await knex("users").insert({
        name: req.body.name,
        email: req.body.email,
        username: req.body.username,
        password: hash,
      });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error message "The result of this line of code is [object Object] when

Recently, I encountered an issue while retrieving an object named userInfo from localStorage in my Angular application. Despite successfully storing the data with localStorage.setItem(), I faced a problem when attempting to retrieve it using localStorage.g ...

Tips for incorporating JSON data into an HTML table

https://i.sstatic.net/WEdge.jpgIn an attempt to showcase JSON data in an HTML table, I want the schoolClassName value to be displayed as a header (th) and the first names of students belonging to that specific schoolClass to appear in a column beneath the ...

Enhancing jqgrid by incorporating cellattr to JSON colmodel

I've been experimenting with adding a custom cellattr function to my colmodel JSON response, but I'm having trouble getting it to work. I've tried applying classes and styles without success, so now I'm attempting to debug by logging so ...

The customized express-validator validation function is malfunctioning

I am currently facing an issue with my code. I have set up validations to check if an email already exists in the database, but this specific validation is not working. Below is a snippet of my code in the Controller: AuthController.register = (req, res) ...

Error: Unable to authenticate password for user "Joshua Rieth" in Knex database connection

Encountering an issue while working on my PostgreSQL database setup using Knex. When I try to run knex migrate:latest, the following error message pops up: Error: password authentication failed for user "Joshua Rieth" at Parser.parseErrorMessage (C:&bs ...

What could be the reason I am unable to choose data properties from the dropdown options?

There are two different dropdowns for clothing types and colors. When a type of clothing is selected from the first dropdown, JSON data will fill the second dropdown with options based on the first dropdown selection. After selecting an option from the se ...

Prevent validation on a particular input field with JQuery validator and Bootstrap

Is there a way to use JQuery validator to validate an entire form except for a specific input? Here is an example code snippet showing how this can be done: jQuery.validator.setDefaults({ debug: true, success: "valid" }); ...

The fragment shader must not declare any varyings with the same name but different type, or statically used varyings without being declared in the vertex shader. An example of this is

I'm struggling with shaders because I want the fog to be reflected in the water using Three.js sky_sun_shader. I added the following code snippet to the fragment Shader: THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk ["fog_fragment" ], ...

The integration of Next.js with a Custom Express Server results in incorrect content types being generated for woff and woff2 files

I recently migrated my Next.js app to a new dedicated cpu server on Digital Ocean, and now I'm facing an issue where my fonts are being served with Content-Type: text/html; charset=utf-8, resulting in a 500 error. Strangely enough, this was not a prob ...

Tips for successfully passing an entire object in the data of a datatable column property

I am currently using Datatables version 1.10.21 and implementing ajax with the column property to generate the datatables successfully. ajax: { url: dataUrl, //using dataUrl variable dataSrc: 'data' }, co ...

The Jquery code encountered an issue where it was unable to access the property 'length' of an undefined

My goal is to submit a form using jQuery and AJAX, which includes file upload functionality. The challenge I'm facing is that the forms are dynamically created, so I need to identify which form was clicked and retrieve its input values. $(document).r ...

Find the item in the pop-up window

When removing a user from my list, a JavaScript popup pops up prompting to confirm the action with two buttons "OK" / "Annuler" : https://i.sstatic.net/BEdH2.png Is there a way to use Selenium to find and interact with these buttons? ...

Errors encountered when using Puppeteer on Kubernetes: "Detached navigation frame" and "Attempting to access main frame too soon"

I have been attempting to execute a nodejs based Docker container on a k8s cluster, but I am encountering persistent errors: Navigation frame was detached Requesting main frame too early In an effort to resolve this issue, I have condensed the code to ...

Implementing position sticky on a div depending on its content text - step by step guide

If the text inside the .newsDate matches the previous or next .newsDate, I want to make its position sticky when scrolling, until it reaches the next .newsMiddleCont div. What I'm trying to achieve: The same date on multiple news items should s ...

What's the best way to include CSS and Javascript in an HTML document?

I'm still getting the hang of CSS and JavaScript. I stumbled upon a cool countdown timer that I'd like to incorporate into my website, but I'm not quite sure how to place it where I envision it. Check out the timer here CSS: html,body{mar ...

How can I pass arguments from a Python command line program (compiled to an EXE) to a JavaScript file?

As I work on developing a node program, I've come across certain abilities that Python possesses which JavaScript lacks, such as utilizing Python-specific modules. To bridge this gap, I made the decision to compile Python files into EXE and then invok ...

"Enhance your website with a dynamic Jssor slider featuring nested slides and vertical

Exploring the idea of merging the nested slider feature with a vertical thumbnail display. Reviewing the source code for examples image-gallery-with-vertical-thumbnail.source.html and nested-slider.source.html, I am wondering how to effectively combine t ...

Checking if a date is before another date in MomentJS without considering the

Recently, I've been utilizing momentJS to identify future dates without a specific day. Below is the code I've been working with along with the outcome: moment('09/2010').isBefore(moment().format('MM/YYYY'), 'day') ...

Detecting changes to DOM elements without using jQueryResponding to DOM element

Suppose I have the following HTML structure: <div id='content'></div> I want to receive an alert when there are height mutations on this element. I thought about using the MutationObserver class for this, but I encountered a specifi ...

Executing a function defined in a .ts file within HTML through a <script> tag

I am attempting to invoke a doThis() function from my HTML after it has been dynamically generated using a <script>. Since the script is loaded from an external URL, I need to include it using a variable in my .ts file. The script executes successfu ...