arb / celebrate

A joi validation middleware for Express.
MIT License
1.33k stars 66 forks source link

Celebrate typing issue #149

Closed kdankert closed 4 years ago

kdankert commented 4 years ago

I got the problem that I cant use celebrate with typescript as it throws an error building the project.

node_modules/celebrate/lib/index.d.ts:11:5 - error TS1038: A 'declare' modifier cannot be used in an already ambient context.

11     declare enum Segments {
       ~~~~~~~

node_modules/celebrate/lib/index.d.ts:72:5 - error TS1038: A 'declare' modifier cannot be used in an already ambient context.

72     declare class CelebrateError {
       ~~~~~~~

node_modules/celebrate/lib/index.d.ts:73:96 - error TS1183: An implementation cannot be declared in ambient contexts.

73         constructor(error: ValidationError, segment: Segments, opts?: { celebrated: boolean }) {}
                                                                                                  ~

Found 3 errors.

This is probably because of the typing file, unfortunately I don't exactly know how they work, I would have tried to solve this problem myself.

arb commented 4 years ago

I don't really know TypeScript well enough to maintain these myself. If anyone from the community could step up here, I'd sure appreciate it! Failing that, I'll probably just delete them since it's a constant maintenance hassle.

kdankert commented 4 years ago

I'm gonna have another look at the file and try to solve this.

kdankert commented 4 years ago

I actually was able to solve this issue, I'll open a merge request for this.

kdankert commented 4 years ago

How do errors behave right now. Does app.use(errors());still need to be called?

When I use the following code I receive an 500 internal sever error instead of a 4xx Response. How am I able to set the error code or is this a bug:

router.post("/", celebrate({
    body: Joi.object().keys({
        data: Joi.array().items(Joi.string())
    })
}), async (req: Request, res: Response) => {
    const data = Promise.all(req.body.data.map(async (test: any) => await convert(test)));
    res.json({data: await data});
});
arb commented 4 years ago

If you don't use errors() then the default express error handler will be used which responds with a 500 and an HTML page. In your code, that async function won't fire because the celebrate call will call next(err) and will use the default error handler.

kdankert commented 4 years ago

So how do I have to change this code snippet in order to work with the celebrate error handler?

kdankert commented 4 years ago

I tried it with app.use(errors()) and without which gives me the same result

kdankert commented 4 years ago

Solved this issue by putting app.use(errors()) below the router.