Chaz Ashley
Chaz Ashley

Reputation: 409

How to end process on specific error in fastify using setErrorHandler?

In my app I'm connecting to a database and then initialize it. I have two custom plugins for that. First plugin connects to DB, and then it registers the second plugin, which initializes the DB (creates tables, domains etc.)

I want to stop process if an error happens inside those two plugins, since without DB connection and initialization the app won't work.

In app.ts I have

const fastify = Fastify({ logger: true });

fastify.register<ConnectAndInitDBConfig>(ConnectAndInitDB, {
  config,
  initSqlPath: 'assets/init.sql',
});

Here is the first plugin ConnectAndInitDB

const ConnectAndInitDB: FastifyPluginCallback<ConnectAndInitDBConfig> = (
  fastify,
  { config, initSqlPath },
  done
) => {
  fastify.register(fastifyPostgres, config); // this connects to the DB (fastify-postgres NPM package)
  fastify.after(err => {
    if (err) {
      fastify.log.error(err);
      return done(err);
    }
    console.log('DB Connected.');
  });
  fastify.register(InitDB, { initSqlPath }); // this initializes the DB
  fastify.after(err => {
    if (err) {
      fastify.log.error(err);
      return done(err);
    }
    console.log('DB Initialized.');
  });

  fastify.setErrorHandler(function errorHandler(error) {
    console.log(`got error`); // this is never called, even if an error happens during initialization of the DB
  });
  done();
};

Here is the second plugin InitDB

const InitDB: FastifyPluginCallback<{ initSqlPath: string }> = async (
  fastify,
  { initSqlPath }: { initSqlPath: string },
  done
) => {
  try {
    const initSql = await (
      await promisify(readFile)(join(resolve(), initSqlPath))
    ).toString();
    await fastify.pg.pool.query(initSql);
    console.log({ initSql });
  } catch (err: Error | unknown) {
    return done(err as Error);
  }
  done();
};

When the error happens inside the InitDB plugin, I see it's logged by fastify logger, but I'm not able to catch it inside the setErrorHandler.

How do I catch any error that happens exactly inside my custom plugins, and let fastify handle all other errors?

Upvotes: 0

Views: 1027

Answers (1)

Manuel Spigolon
Manuel Spigolon

Reputation: 12890

You don't need the errorHandler because it is triggered for HTTP errors, not for the fastify server startup errors.

It is quite simple to archive your needs:

// when there is an async func, the `done` arg must be removed
const ConnectAndInitDB = async function (fastify, { config, initSqlPath }) {
  await fastify.register(fastifyPostgres, config)
  console.log('DB Connected.')

  try {
    await fastify.register(InitDB, { initSqlPath }) 
    console.log('DB Initialized.')
  } catch (error) {
    console.log(`got error`)
    throw error // bubble up the error so fastify server will not start
  }
}

Upvotes: 1

Related Questions