0

In my Node.js application I´m using fastify as framework together with some plugins (i18next). I´m using i18next for translation (is working properly in preHandler and handler hooks) and want to customize all errors by using my translations via i18next in my custom error handler (via fastify setErrorHandler method).

Here is my coding so far (from top to bottom):

import fastify from "fastify";
import routes from "./routes/routes.js";


import i18next from "./config/i18next.js";
import i18nextMiddleware from "i18next-http-middleware";

const app = fastify({
    logger: true,
    ajv: {
        customOptions: {
            allErrors: true,
            $data: true
        }
    },
});

app.register(i18nextMiddleware.plugin, { i18next });

app.register(routes, { prefix: '/api/v1' });

app.setErrorHandler((error, request, reply) => {
    console.log('request.t: ', request.t);
    if (error.validation) {
        // other coding ...
        reply.send(error);
    }
});

(async () => {
    try {
        await app.listen(process.env.PORT);
        console.log(`Server started listening on port ${process.env.PORT}`);
    } catch (err) {
        app.log.error(err);
    }
})();

Inside the setErrorHandler (which is sync) I want to use the initialized t() method from i18next instance passed to request object (this is working for all my routes in the preHandler and handler hooks) but is not working in the setErrorHandler, as I´ll get undefined when an error occours. I know the setErrorHandler is sync and all plugin registration will be handled async, but didn´t solved it yet.

What I´ve also tried is to do the setErrorHandler call in the after() hook when registering the i18next plugin, but the result is the same. I know I´m missing a small detail, but any tips are appreciated, as I´m spinning my head around this since hours.

stefano
  • 315
  • 2
  • 16

1 Answers1

2

This happens because the i18next-http-middleware plugin adds the t method to the request object on a preHandler hook that is executed after the JSON validation step:

export function plugin (instance, options, next) {
  const middleware = handle(options.i18next, options)
  instance.addHook('preHandler', (request, reply, next) => middleware(request, reply, next))
  return next()
}

source

You should be able to write a workaround like this:

import i18nextMiddleware from "i18next-http-middleware";

// ....

const middleware = i18nextMiddleware.handle({})
app.addHook('preValidation', (request, reply, next) => middleware(request, reply, next))

I think that is a bug of the module tho

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73