Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fn invalid parameters after 4.5.1 update #220

Closed
2 tasks done
mellinas314 opened this issue Jul 19, 2023 · 5 comments
Closed
2 tasks done

fn invalid parameters after 4.5.1 update #220

mellinas314 opened this issue Jul 19, 2023 · 5 comments

Comments

@mellinas314
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.20.0

Plugin version

4.5.1

Node.js version

20

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.3

Description

After updating plugin to version 4.5.1, my previously existing project has stopped to work with the following error:

Argument of type '(server: FastifyInstance, _: FastifyPluginOptions, done: (err?: Error | undefined) => void) => Promise<void>' is not assignable to parameter of type 'FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>'.

I've been loking for some update where this change is described and how to update my code to make it works, but can't find anything (downgrading to version 4.5.0, it works again with no problem), but I can't find what I need to change in my call to fp() to make it works with new version.

Steps to Reproduce

After update to fastify-plugin 4.5.1, just try to call fp() with previous working parameters, like:

 fp(async (server: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error | undefined) => void)  => {
    ........
    done();
});

and it will return following error:

Argument of type '(server: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error | undefined) => void) => Promise<void>' is not assignable to parameter of type 'FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>'.

Expected Behavior

To keep working as previous versions.

@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 19, 2023

You mixed async with callback style. So the typescript compilation error is thrown correctly.

Either use callback style and remove the async or use async and remove the done parameter and its use.

@mellinas314
Copy link
Author

You mixed async with callback style. So the typescript compilation error is thrown correctly.

Either use callback style and remove the async or use async and remove the done parameter and its use.

Absolutely right, thanks for the fast reply! As it was working previously and I was not fully understanding the error message, I open this issue. Sorry for the confusion; i close it as it was my fault :)

Thanks!

@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 19, 2023

Dont worry. I am actually happy for this feedback, as it shows that the changes made for 4.5.1 are working as expected. ;)

@lightify97
Copy link

In the following code I'm not using the async function but still getting the same error:

"use strict";

import { FastifyInstance, FastifyPluginOptions } from "fastify";
import fp from "fastify-plugin";
import { Redis, ReplyError } from "ioredis";

function fastifyKeydbPlugin(
    fastify: FastifyInstance,
    options: FastifyPluginOptions,
    next: Function
) {
    const { namespace, url, closeClient = false, ...redisOptions } = options;

    let client = options.client || null;

    if (namespace) {
        if (!fastify.keydb) {
            fastify.decorate("keydb", Object.create(null));
        }

        if (fastify.keydb[namespace]) {
            return next(
                new Error(
                    `Redis '${namespace}' instance namespace has already been registered`
                )
            );
        }

        const closeNamedInstance = (fastify: FastifyInstance) => {
            return fastify.keydb[namespace].quit();
        };

        if (client) {
            if (closeClient === true) {
                fastify.addHook("onClose", closeNamedInstance);
            }
        } else {
            try {
                if (url) {
                    client = new Redis(url, redisOptions);
                } else {
                    client = new Redis(redisOptions);
                }
            } catch (err) {
                return next(err);
            }

            fastify.addHook("onClose", closeNamedInstance);
        }

        fastify.keydb[namespace] = client;
    } else {
        if (fastify.keydb) {
            return next(new Error("Keydb has already been registered"));
        } else {
            if (client) {
                if (closeClient === true) {
                    fastify.addHook("onClose", close);
                }
            } else {
                try {
                    if (url) {
                        client = new Redis(url, redisOptions);
                    } else {
                        client = new Redis(redisOptions);
                    }
                } catch (err) {
                    return next(err);
                }

                fastify.addHook("onClose", close);
            }

            fastify.decorate("keydb", client);
        }
    }

    // Testing this make the process crash on latest TAP :(
    /* istanbul ignore next */
    const onEnd = function (err: any) {
        client
            .off("ready", onReady)
            .off("error", onError)
            .off("end", onEnd)
            .quit();

        next(err);
    };

    const onReady = function () {
        client.off("end", onEnd).off("error", onError).off("ready", onReady);

        next();
    };

    // Testing this make the process crash on latest TAP :(
    /* istanbul ignore next */
    const onError = function (err: { code: string }) {
        if (err.code === "ENOTFOUND") {
            onEnd(err);
            return;
        }

        // Swallow network errors to allow ioredis
        // to perform reconnection and emit 'end'
        // event if reconnection eventually
        // fails.
        // Any other errors during startup will
        // trigger the 'end' event.
        if (err instanceof ReplyError) {
            onEnd(err);
        }
    };

    // ioredis provides it in a .status property
    if (client.status === "ready") {
        // client is already connected, do not register event handlers
        // call next() directly to avoid ERR_AVVIO_PLUGIN_TIMEOUT
        next();
    } else {
        // ready event can still be emitted
        client.on("end", onEnd).on("error", onError).on("ready", onReady);

        client.ping();
    }
}

function close(fastify: FastifyInstance) {
    return fastify.keydb.quit();
}

const fastifyKeydb = fp(fastifyKeydbPlugin, {
    fastify: "4.x",
    name: "@fastify/redis",
});

export default fastifyKeydb;

This is the error I'm getting.

error TS2345: Argument of type '(fastify: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>, options: FastifyPluginOptions, next: Function) => any' is not assignable to parameter of type 'FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>'.
  Target signature provides too few arguments. Expected 3 or more, but got 2.

132 const fastifyKeydb = fp(fastifyKeydbPlugin, {

@Eomm
Copy link
Member

Eomm commented Sep 17, 2023

@lightify97 I think your issue is due the return next(err);, try this instead:

next(err);
return

If it does not work, please open a new issue with a Minimal, Reproducible Example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants