简体   繁体   中英

Middleware getting called for error handling but not handling response

I am trying to handle errors by returning json, but my error handler (while being called, logs in console) wont return what I am trying to return. Here is the handler:

const handleError = function(err, req, res, next) {
    console.log(err);
    res.setHeader('Content-Type', 'application/json');
    res.status(500);
    res.send(JSON.stringify(error));
}

But I get returned a render function that translate to the following returned to me as the user:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Error</title>
    </head>
    <body>
        <pre>Invalid token with reason JsonWebTokenError: jwt malformed</pre>
    </body>
</html>

So it will still log the error but unless I return an error in my actual function it wont return as intended, aka the following function does return a json error as written:

const view = function(req,  res, model, settings = {}, callback)  {
    let { params } = req;
    let { _id } = params;
    let { select, limit, sort } = settings;
    let query = model.findById(_id);
    if (select) query.select(select);
    if (sort) query.sort(sort);
    if (limit) query.limit(limit);
    query.exec(function(err, data) {
        if(callback) {
            callback(err,data);
        }else{
            if (err) return res.status(400).json({ 'Error': err.message });
            if (!data) return res.status(404).json({ 'Error': `No document with id ${_id} found` });
            return res.status(200).json(data);
        }
    });
}

Here is how I register my middlewares

let app = express();
app.server = http.createServer(app);

// logger
app.use(morgan('dev'));

// 3rd party middleware
app.use(cors({
    exposedHeaders: config.corsHeaders
}));

// Custom error handling 
app.use(api.handleError);

//Set body as json as recieved
app.use(bodyParser.json({
    limit : config.bodyLimit
}));

When I read the express documentation on error handling, it seems to me like you're supposed to throw new Error() (or call next() , depending on the sync/async nature of your handlers) in order to get the error handler working.

In your code above, I see you return res.status().json() -- which I don't think is the same thing.

You've pointed out that unless I return an error in my actual function, it won't return as intended -- so it sounds like you already know what's happening.

You also mentioned that handleError should return JSON -- why not change this:

res.status(500);
res.send(JSON.stringify(error));

...to...

res.status(500).json(error)

That should give you what you need.

Try to add error handler middleware bellow your route. Example:

app.get('/', indexHandler)
//call next(err) in indexHandler if there is an error
app.use(errorHandler)

The answer is very simple install express-async-errors https://www.npmjs.com/package/express-async-errors

run  npm install express-async-errors

and require it at the top of your app.js file

require('express-async-errors')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM