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

Typing error when using onError with derive #653

Closed
nxht opened this issue May 22, 2024 · 4 comments
Closed

Typing error when using onError with derive #653

nxht opened this issue May 22, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@nxht
Copy link

nxht commented May 22, 2024

What version of Elysia.JS is running?

1.0.21

What platform is your computer?

Linux 5.15.146.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

import { Elysia } from 'elysia';

const plugin = new Elysia({ name: 'test' }).derive({ as: 'global' }, () => {
  return {
    test: 'test',
  };
});

const app = new Elysia()
  .use(plugin)
  .onError(({ test }) => {
    console.log(test);
  })
  .get('/', ({ test }) => {
    throw new Error(test);
  })
  .listen(7003);

console.log(`http://${app.server?.hostname}:${app.server?.port}`);

What is the expected behavior?

No type error as the code works well.
Type of test should be inferred as string | undefined or at least string.
Also, there was no type error when tested on elysia@1.0.20

What do you see instead?

image

Additional information

Same code on elysia@1.0.20

image

@nxht nxht added the bug Something isn't working label May 22, 2024
@RappyTV
Copy link

RappyTV commented May 30, 2024

My code looks like this:

function fetchI18n(app: Elysia) {
    return app.derive({ as: 'global' }, ({ headers }) => {
        const header = headers[`x-minecraft-language`] || `en_us`;
        const locales = getLocales(header);
        return {
            i18n: (path: string) => getPath(path, locales)
        };
    });
}

const elysia = new Elysia()
.use(fetchI18n)
.onError(({ code, set, error, i18n }) => {
    if(code == 'VALIDATION') {
        set.status = 422;
        return { error: i18n(error.message) };
    } else if(code == 'NOT_FOUND') {
        set.status = 404;
        return { error: i18n(`error.notFound`) };
    } else {
        set.status = 500;
        Logger.error(error.message);
        return { error: i18n(`error.unknownError`) };
    }
})
.listen(config.port);

I don't get any type errors and typescript also says that the function i18n in Elysia#onError exists but as soon as I run into an error (requesting a non-existent route for example) I get this error:

122 |     if(code == 'VALIDATION') {
123 |         set.status = 422;
124 |         return { error: i18n(error.message) };
125 |     } else if(code == 'NOT_FOUND') {
126 |         set.status = 404;
127 |         return { error: i18n(`error.notFound`) };
                              ^
TypeError: i18n is not a function. (In 'i18n("error.notFound")', 'i18n' is undefined)
      at /.../src/index.ts:127:25
GET - /test failed

@nxht
Copy link
Author

nxht commented May 31, 2024

My code looks like this:

function fetchI18n(app: Elysia) {
    return app.derive({ as: 'global' }, ({ headers }) => {
        const header = headers[`x-minecraft-language`] || `en_us`;
        const locales = getLocales(header);
        return {
            i18n: (path: string) => getPath(path, locales)
        };
    });
}

const elysia = new Elysia()
.use(fetchI18n)
.onError(({ code, set, error, i18n }) => {
    if(code == 'VALIDATION') {
        set.status = 422;
        return { error: i18n(error.message) };
    } else if(code == 'NOT_FOUND') {
        set.status = 404;
        return { error: i18n(`error.notFound`) };
    } else {
        set.status = 500;
        Logger.error(error.message);
        return { error: i18n(`error.unknownError`) };
    }
})
.listen(config.port);

I don't get any type errors and typescript also says that the function i18n in Elysia#onError exists but as soon as I run into an error (requesting a non-existent route for example) I get this error:

122 |     if(code == 'VALIDATION') {
123 |         set.status = 422;
124 |         return { error: i18n(error.message) };
125 |     } else if(code == 'NOT_FOUND') {
126 |         set.status = 404;
127 |         return { error: i18n(`error.notFound`) };
                              ^
TypeError: i18n is not a function. (In 'i18n("error.notFound")', 'i18n' is undefined)
      at /.../src/index.ts:127:25
GET - /test failed

@RappyTV
For your case,
Based on https://elysiajs.com/life-cycle/overview.html,
Finding route is done before derive/transform lifecycle, so i18n actually can be undefined, in case of 'NOT_FOUND' error.
So the correct typing would be Function | undefined and you should handle the undefined case

@RappyTV
Copy link

RappyTV commented May 31, 2024

@RappyTV

For your case,

Based on https://elysiajs.com/life-cycle/overview.html,

Finding route is done before derive/transform lifecycle, so i18n actually can be undefined, in case of 'NOT_FOUND' error.

So the correct typing would be Function | undefined and you should handle the undefined case

@nxht
The docs are pretty confusing then as they say that errors are at the last (eighth) position in the lifecycle

@nxht
Copy link
Author

nxht commented Jul 18, 2024

Issue seems to be fixed in 1.1.3 (similar error with #722 I guess)

@nxht nxht closed this as completed Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants