session icon indicating copy to clipboard operation
session copied to clipboard

Allow null Session in SessionCallback when there is an error.

Open kylerush opened this issue 3 years ago • 7 comments

It looks like the existing code support an error being thrown on store.get, however, the type definition SessionCallback for the callback function on store.get requires a Session type variable for the session argument. This change would not cause the type check to fail when you call the store.get callback function like so:

callback(new Error("Some error"), null)

This change also exports the SessionCallback type on the FastifySession type so that we can specify that our store.get callback function is of type FastifySession.SessionCallback.

Checklist

kylerush avatar Dec 20 '22 00:12 kylerush

Thanks @climba03003! I'm going to commit your suggestion and then would like to propose one more change to export the SessionCallback type. Will add that change shortly.

kylerush avatar Dec 20 '22 11:12 kylerush

@climba03003 PTAL

Uzlopak avatar Dec 24 '22 18:12 Uzlopak

@climba03003 this new type definition seems to not be working, or at least I don't understand how it should work.

With the suggestion change, typescript tells me:

  1. Argument of type 'null' is not assignable to parameter of type 'Error'.
  2. Argument of type 'Session' is not assignable to parameter of type 'undefined'.
Screenshot 2022-12-26 at 11 51 43 AM

I am not quite sure how to solve this problem. Is seems this union type definition doesn't quite work for the use case. Any idea?

I tried to change it to an overloaded function, but that caused the arguments in the callback function accepts to lose their types: Screenshot 2022-12-26 at 12 08 20 PM

kylerush avatar Dec 26 '22 17:12 kylerush

CI is not happy

mcollina avatar Dec 28 '22 18:12 mcollina

Yeah it needs a little more work. The new tuple type seems to be causing issues as currently implemented. Will try to knock this out tomorrow.

kylerush avatar Dec 28 '22 23:12 kylerush

Hey folks 👋 I see this one didn't get finished and I'd like to have it fixed as well.

I took some time to tinker around with CallbackSession type and found out that we don't really have a flawless solution for this case. Here are a few implementations that I tested out:

Intersection

type Callback = ( ((err: Error) => void) & ((err: null, result: number) => void) );

const getSession = (callback: Callback) => {
    callback(new Error()); // correct
    callback(new Error(), 5); // throws error, correct
    callback(null, 5); // correct
}

getSession((error) => {
    // parameters properly typed, TS compiles
    return;
})

getSession((error, result) => {
    // parameters properly typed, but TS does not compile
    return;
})

Function overload

type Callback = {
    (err: Error): void;
    (err: null, result: number): void;
}

const getSession = (callback: Callback) => {
    callback(new Error()); // correct
    callback(new Error(), 5); // throws error, correct
    callback(null, 5); // correct
}

getSession((error) => {
    // parameters properly typed, TS compiles
    return;
})

getSession((error, result) => {
    // parameters properly typed, but TS does not compile
    return;
})

You can see within the comments that those do not work as intended due to how TypeScript works. I think that the most optimal way we could go is this:

type Callback = {
    (err: Error, result?: undefined): void;
    (err: null, result: number): void;
}

const getSession = (callback: Callback) => {
    callback(new Error()); // correct
    callback(new Error(), 5); // throws error, correct
    callback(null, 5); // correct
}

getSession((error) => {
    // parameters properly typed but are not fully precise, TS compiles
    return;
})

getSession((error, result) => {
    // parameters properly typed but are not fully precise, TS compiles
    return;
})

This way we lose the preciseness of the arguments of the callback that we pass to the get function, but at least callback calls work as intended.

@kylerush Let me know if you have time to finish this off. If not, please let me know - I'll create a separate PR with the fix.

Also, let me know what you all folks think!

jsardev avatar Mar 27 '23 10:03 jsardev

@sarneeh go ahead and open a fresh PR!

mcollina avatar Mar 28 '23 07:03 mcollina