如何使用Express.js指定HTTP错误代码?

255

我已经尝试过:

app.get('/', function(req, res, next) {
    var e = new Error('error message');
    e.status = 400;
    next(e);
});

并且:

app.get('/', function(req, res, next) {
    res.statusCode = 400;
    var e = new Error('error message');
    next(e);
});

但总是会报告500的错误代码。


1
我的答案可能会对相关问题有所帮助:http://stackoverflow.com/questions/10170857/can-i-reuse-the-express-js-error-view/10556093#10556093 - Pickels
2
请问您能否更新已接受的回答? - Dan Mandle
这个回答解决了您的问题吗?如何使用Express / Node以编程方式发送404响应? - Henke
13个回答

422

64
使用最新版本的API加1。如果你想发送更多的数据,请使用链式结构: res.status(400).json({ error: 'message' }) - TyMayn
1
@Mikel 如果你没有响应变量,那么你就无法发送响应。 - Dan Mandle
5
现在这些都已经过时了,你应该使用res.sendStatus(401) - Cipi
1
如果在结尾加上 res.send('Then you shall die'),这个响应会更完整。 - goodvibration
2
@Cipi,你有这方面的来源吗?文档没有表明.status()已被弃用。.sendStatus()只是一个缩写,用于.status(code).send(codeName),其中codeName是给定code的标准HTTP响应文本。 - James Coyle
显示剩余3条评论

120
一个简单的一行代码;
res.status(404).send("Oh uh, something went wrong");

45

我希望以这种方式集中创建错误响应:

app.get('/test', function(req, res){
  throw {status: 500, message: 'detailed message'};
});

app.use(function (err, req, res, next) {
  res.status(err.status || 500).json({status: err.status, message: err.message})
});

所以我一直都有相同的错误输出格式。

PS:当然你可以创建一个对象来扩展标准错误,就像这样:extend the standard error

const AppError = require('./lib/app-error');
app.get('/test', function(req, res){
  throw new AppError('Detail Message', 500)
});

'use strict';

module.exports = function AppError(message, httpStatus) {
  Error.captureStackTrace(this, this.constructor);
  this.name = this.constructor.name;
  this.message = message;
  this.status = httpStatus;
};

require('util').inherits(module.exports, Error);

很棒的解决方案,但这给了我UnhandledPromiseRejectionWarning错误。如何确保在我们的错误中间件中处理错误。 - Rahul Purohit
async/await在express中不是开箱即用的,可以尝试使用https://github.com/fastify/fastify。 - Manuel Spigolon
只有在路由是同步的情况下,throw 才起作用。如果是异步路由,你必须手动调用 next()。我猜(但没有尝试过),你可以将在 throw 中显示的相同对象传递给 next() - Mitya

20

在Express 4.0中,他们做得很好 :)

res.sendStatus(statusCode)
// Sets the response HTTP status code to statusCode and send its string representation as the response body.

res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

//If an unsupported status code is specified, the HTTP status is still set to statusCode and the string version of the code is sent as the response body.

res.sendStatus(2000); // equivalent to res.status(2000).send('2000')

19

你可以使用res.send('OMG :(', 404);简化为res.send(404);


1
但我希望将错误代码发送到eventHandler中间件,以便显示express的自定义错误页面。 - tech-man
19
如果你正在阅读此内容并且是在2016年以后,需要知道根据Express 4.x版本,res.send(404)已经过时了。现在使用res.sendStatus(404)。详情请参考http://expressjs.com/en/api.html#res.sendStatus - 0xRm

13

根据我在Express 4.0中所看到的,这对我有效。这是一个需要身份验证的中间件示例。

function apiDemandLoggedIn(req, res, next) {

    // if user is authenticated in the session, carry on
    console.log('isAuth', req.isAuthenticated(), req.user);
    if (req.isAuthenticated())
        return next();

    // If not return 401 response which means unauthroized.
    var err = new Error();
    err.status = 401;
    next(err);
}

11

捆绑在某些(也许是旧的?)express版本中的errorHandler中间件的版本似乎已经将状态码硬编码了。另一方面,此处记录的版本http://www.senchalabs.org/connect/errorHandler.html允许您完成您正在尝试的操作。因此,建议升级到最新版本的express/connect。


11

我尝试了

res.status(400);
res.send('message');

但是它给了我一个错误

(node:208) 未处理的Promise拒绝警告:错误:无法设置标题,因为它们已经被发送。

这对我有用

res.status(400).send(yourMessage);

9

虽然这个问题已经有一段时间了,但是在谷歌上仍然会被提及。在当前版本的Express(3.4.0)中,您可以在调用next(err)之前更改res.statusCode:

res.statusCode = 404;
next(new Error('File not found'));

下一个函数是做什么的? - Stephan Kristyn
next 调用下一个处理程序,在 express.js 中通常尝试呈现错误页面。 - Firanto

8

Express已经废弃了res.send(body, status)

请使用res.status(status).send(body)res.sendStatus(status)代替。


感谢。处理中间件警告。 - Ashok

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接