node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7k stars 680 forks source link

TypeScript - Unable to access FormidableError on formidable.errors #972

Closed FredTheNoob closed 3 months ago

FredTheNoob commented 3 months ago

Support plan

Context

What are you trying to achieve or the steps to reproduce?

I'd like to access the FormidableError object when I'm throwing an error, this is my use case:

router.post("/user/upload", validateAuthToken, async (req, res, next) => {
    const form = formidable({
        maxFiles: 1, 
        keepExtensions: true, 
        maxFileSize: MAX_FILE_SIZE, 
        allowEmptyFiles: false,
    });

    form.parse(req, async (err, fields, files) => {
        if (err) {
            if (err instanceof formidable.errors.FormidableError) {
                return res.status(err.httpCode ? err.httpCode : 400).send(err.message);
            }
        }
    })
});

In postman I'm passing multipart formdata, where I purposely input a file above the MAX_FILE_SIZE, the error is thrown properly, but I just seem unable to get the FormidableError object.

What was the result you got?

TypeError: Cannot read properties of undefined (reading 'FormidableError')

What result did you expect?

That the above use case works

tunnckoCore commented 3 months ago

That's because errors export named variables with "error codes", not directly the error class.

That's a good point, we'll fix it. I think you can access the class on errors.default.

image

GrosSacASac commented 3 months ago

Where did you see that way of using this variable ?

FredTheNoob commented 3 months ago

Where did you see that way of using this variable ?

Nowhere, in retrospect I don't know if this is even the right way to do it at all 😅

FredTheNoob commented 3 months ago

That's because errors export named variables with "error codes", not directly the error class.

That's a good point, we'll fix it. I think you can access the class on errors.default.

image

That doesn't seem to work 😔

image

GrosSacASac commented 3 months ago
import formidable, {errors as FormidableErrors} from 'formidable';

console.log(FormidableErrors.default);

formidable.errors is not the same as FormidableErrors. The way you import is critical here

https://github.com/node-formidable/formidable/blob/master/src/FormidableError.js

or

As you can see all errors have a httpCode

So you could do the following

if (err.httpCode !== undefined)

FredTheNoob commented 2 months ago

I don't know how to apply that to my example @GrosSacASac. I've tried this:

import formidable, {errors as FormidableErrors} from 'formidable';

....

form.parse(req, async (err, fields, files) => {
        if (err) {
            if (err instanceof FormidableErrors.FormidableError) {
                if (err.httpCode !== undefined) {
                    return res.status(err.httpCode).send(err.message);
                }
            }
        }
});

But get this error:

file:///root/easyrate/easyrate-backend/js/routes/user.js:283
            if (err instanceof FormidableErrors.FormidableError) {
                    ^

TypeError: Right-hand side of 'instanceof' is not an object
    at file:///root/easyrate/easyrate-backend/js/routes/user.js:283:21
    at zalgoSafe (/root/easyrate/easyrate-backend/node_modules/dezalgo/dezalgo.js:20:10)
    at f (/root/easyrate/easyrate-backend/node_modules/once/once.js:25:25)
    at IncomingForm.<anonymous> (file:///root/easyrate/easyrate-backend/node_modules/formidable/src/Formidable.js:225:7)
    at IncomingForm.emit (node:events:519:28)
    at IncomingForm._error (file:///root/easyrate/easyrate-backend/node_modules/formidable/src/Formidable.js:495:10)
    at Stream.<anonymous> (file:///root/easyrate/easyrate-backend/node_modules/formidable/src/Formidable.js:385:14)
    at Stream.emit (node:events:519:28)
    at MultipartParser.dataPropagation (file:///root/easyrate/easyrate-backend/node_modules/formidable/src/plugins/multipart.js:103:22)
    at MultipartParser.emit (node:events:531:35)

Node.js v21.7.1
import formidable, {errors as FormidableErrors} from 'formidable';

console.log(FormidableErrors.default);

formidable.errors is not the same as FormidableErrors. The way you import is critical here

https://github.com/node-formidable/formidable/blob/master/src/FormidableError.js

or

As you can see all errors have a httpCode

So you could do the following

if (err.httpCode !== undefined)

GrosSacASac commented 2 months ago

if (err instanceof FormidableErrors.default)

FredTheNoob commented 2 months ago

That doesn't work either

image

I have imported like so:

import formidable, {errors as FormidableErrors} from 'formidable';
Corpra commented 2 months ago

@FredTheNoob

I'm doing this successfully with the following:

import { errors as formidableErrors } from 'formidable';

// ...

if e (instanceof formidableErrors.FormidableError)

But I'm on v2 of formidable, not sure if that matters.