Search code examples
javascriptexpresserror-handlingasync-awaitmulter

How to return an error back to ExpressJS from middleware?


I am using [Multer][1] as middleware to process multipart form data. Multer offers some configuration options for setting destination of file uploads and names called diskStorage. It is within this area that one can do some error checking and control whether Multer authorises a file upload or not.

My Express route is basically this:

expressRouter.post(['/create'],
    MulterUpload.single("FileToUpload"), // if this throws an error then have Express return that error to the user
    async function(req, res) {
      // handle the form text fields in req.body here
});

MulterUpload.single() takes the file input field named "FileToUpload" and sends it off to do this:

const MulterUpload = multer({
    storage: MulterStorage
)}

const MulterStorage = multer.diskStorage({
    destination: async function (req, file, cb) {
        try {
            if ("postID" in req.body && req.body.postID != null && req.body.postID.toString().length) {

                const Result = await api.verifyPost(req.body.postID)
                if (Result[0].postverified == false) {
                    const Err = new Error("That is not your post!");
                    Err.code = "ILLEGAL_OPERATION";
                    Err.status = 403;
                    throw(Err); // not authorised to upload
                } else {
                    cb(null, '/tmp/my-uploads') // authorised to upload
                }
            }
        } catch (err) {
            // How do I return the err back to Express so it can send it to the user? The err is an unresolved Promise as I am using async/await
        }
    }
    ,
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
    }
})

I just can't seem to work out how to get the error from MulterStorage back to Express so that it is sent back the browser/user as an error. [1]: https://www.npmjs.com/package/multer


Solution

  • You can call the completion callback with an Error object as the first argument. So, instead of

    cb(null, someResult)
    

    you call the callback with an error object

    cb(new Error("I got a disk error"));
    

    Then, if you have multer set up as plain middleware, this will result in next(err) being called and in Express, your generic error handler will receive the error.

    Here are a couple examples:

    https://www.npmjs.com/package/multer#error-handling

    https://github.com/expressjs/multer/issues/336#issuecomment-242906859