Home > Net >  How to fix in KnexJs the error destroy of undefined
How to fix in KnexJs the error destroy of undefined

Time:01-05

In my Node application, I'm running a script to generate a DB that uses the KnexJs query builder and the PostgreSQL

  • "node": "~14.17.6"
  • "knex": "^0.95.15"
  • "pg": "^8.7.1"

The error I'm getting

Cannot read property 'destroy' of undefined
TypeError: Cannot read property 'destroy' of undefined
    at process.value (/app/node_modules/knex/lib/knex-builder/make-knex.js:91:26)
    at process.emit (events.js:315:20)
    at process.exit (internal/process/per_thread.js:169:15)
    at success (/app/node_modules/knex/bin/utils/cli-config-utils.js:76:11)
    at Command.<anonymous> (/app/node_modules/knex/bin/cli.js:236:9)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

The script I'm running is as follow

const conn = {
  host: process.env.POSTGRES_HOST,
  database: process.env.POSTGRES_USER,
  user: process.env.POSTGRES_USER,
  password: process.env.POSTGRES_PASSWORD,
  port: process.env.POSTGRES_PORT,
  charset: 'utf8',
};

const databaseName = process.env.POSTGRES_DB;

const knex = require('knex')({ client: 'pg', connection: conn });

knex
  .raw('CREATE DATABASE ??', databaseName)
  .then(() => console.info('Successfully created db: '   databaseName))
  .catch((err) =>
    console.warn('Warning: Unable to create db. Probably already exists.', err)
  )
  .finally(() => knex.destroy())
  .then(() => {
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });
    return connection2
      .raw('CREATE EXTENSION IF NOT EXISTS citext')
      .then(() => console.info('Successfully created extension citext'))
      .catch((err) => console.error('Unable to create extension citext.', err))
      .finally(() => connection2.destroy());
  })
  .then(() => process.exit(0));

I'm unable to understand what causes the issue and why

CodePudding user response:

I think the issue probably is due to misunderstanding about what is the knex instance and what is the connection instance.

In this part:

const knex = require('knex')({ client: 'pg', connection: conn });

You defined a connection using the knex module. So, when you invoke "knex" to create a second connection below:

 .then(() => {
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });

connection2 is not a connection because knex in this context is the desired connection. You could use the previously knex connection object.

To avoid these issues, I recommend you to separate things and rename variables to make it more explainable:

const knex = require('knex') // this is the knex module

const connection = knex({ client: 'pg', connection: conn }) // This is a connection using knex

// So you should use `connection` instead `knex`, as you are using the connection instance to perform queries

connection
  .raw('CREATE DATABASE ??', databaseName)

// ...

.then(() => {
    // Now this should work and return a connection
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });

    // But as connection2 is actually the same of connection, it could be
    // const connection2 = connection;
    return connection2 // or return connection
      .raw('CREATE EXTENSION IF NOT EXISTS citext')
      .then(() => console.info('Successfully created extension citext'))
      .catch((err) => console.error('Unable to create extension citext.', err))
      .finally(() => connection2.destroy());
  })

Another point to talk about is that if is really necessary to ends the connection and to create another one just after first destroy() call. As you can have an instance to the connection, so you can use it while you are performing queries and just destroy it once if it is not necessary anymore.

  •  Tags:  
  • Related