express中的错误处理
错误处理
定义错误处理中间件和定义其他中间件一样,除了需要 4 个参数,而不是 3 个,其格式如下 (err, req, res, next)。例如:
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
在其他 app.use() 和路由调用后,最后定义错误处理中间件,比如:
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
// 业务逻辑
});
中间件返回的响应是随意的,可以响应一个 HTML 错误页面、一句简单的话、一个 JSON 字符串,或者其他任何您想要的东西。
为了便于组织(更高级的框架),您可能会像定义常规中间件一样,定义多个错误处理中间件。比如您想为使用 XHR 的请求定义一个,还想为没有使用的定义一个,那么:
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
app.use(bodyParser());
app.use(methodOverride());
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);
logErrors 将请求和错误信息写入标准错误输出、日志或类似服务:
function logErrors(err, req, res, next) {
console.error(err.stack);
next(err);
}
clientErrorHandler 的定义如下(注意这里将错误直接传给了 next):
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
res.status(500).send({ error: 'Something blew up!' });
} else {
next(err);
}
}
errorHandler 能捕获所有错误,其定义如下:
function errorHandler(err, req, res, next) {
res.status(500);
res.render('error', { error: err });
}
如果向 next() 传入参数(除了 ‘route’ 字符串),Express 会认为当前请求有错误的输出,因此跳过后续其他非错误处理和路由/中间件函数。如果需做特殊处理,需要创建新的错误处理路由,如下节所示。
如果路由句柄有多个回调函数,可使用 ‘route’ 参数跳到下一个路由句柄。比如:
app.get('/a_route_behind_paywall',
function checkIfPaidSubscriber(req, res, next) {
if(!req.user.hasPaid) {
// 继续处理该请求
next('route');
}
}, function getPaidContent(req, res, next) {
PaidContent.find(function(err, doc) {
if(err) return next(err);
res.json(doc);
});
});
在这个例子中,句柄 getPaidContent 会被跳过,但 app 中为 /a_route_behind_paywall 定义的其他句柄则会继续执行。
next() 和 next(err) 类似于 Promise.resolve() 和 Promise.reject()。它们让您可以向 Express 发信号,告诉它当前句柄执行结束并且处于什么状态。next(err) 会跳过后续句柄,除了那些用来处理错误的句柄。
缺省错误处理句柄
Express 内置了一个错误处理句柄,它可以捕获应用中可能出现的任意错误。这个缺省的错误处理中间件将被添加到中间件堆栈的底部。
如果你向 next() 传递了一个 error ,而你并没有在错误处理句柄中处理这个 error,Express 内置的缺省错误处理句柄就是最后兜底的。最后错误将被连同堆栈追踪信息一同反馈到客户端。堆栈追踪信息并不会在生产环境中反馈到客户端。
设置环境变量 NODE_ENV 为 “production” 就可以让应用运行在生产环境模式下。
如果你已经开始向 response 输出数据了,这时才调用 next() 并传递了一个 error,比如你在将向客户端输出数据流时遇到一个错误,Express 内置的缺省错误处理句柄将帮你关闭连接并告知 request 请求失败。
因此,当你添加了一个自定义的错误处理句柄后,如果已经向客户端发送包头信息了,你还可以将错误处理交给 Express 内置的错误处理机制。
function errorHandler(err, req, res, next) {
if (res.headersSent) {
return next(err);
}
res.status(500);
res.render('error', { error: err });
express中的错误处理的更多相关文章
- 在IIS Express中调试时无法读取配置文件 错误
在IIS Express中调试代码时,如果出现"无法读取配置文件"的问题(如图),这种情况是IIS Express的"applicationhost.config&quo ...
- node express中使用static的错误
使用express中的static可以设置文件存储路径,比如js存在于public/js//demo.js这个时候可以将js文件夹设置为专门存储js的路径,代码如下: app.use('/javasc ...
- 精华 对express中next函数的一些理解
关于next主要从三点来进行说明: next的作用是什么? 我们应该在何时使用next? next的内部实现机制是什么? Next的作用 我们在定义express中间件函数的时候都会将第三个参 ...
- Navicat 远程连接SQL Server 2014 Express 报08001错误
场景:Navicat 远程连接SQL Server 2014 Express 报08001错误,经查验防火墙端口1434,1433已经打开 过程:1. 一开始觉得是连接名称问题,使用IP地址或者主机名 ...
- Koa 中的错误处理
不像 express 中在末尾处注册一个声明为 (err, req, res, next) 中间件的方式,koa 刚好相反,在开头进行注册. app.use(async (ctx, next) =&g ...
- [转] 对express中next函数的一些理解
最近公司在使用node做前后端分离,采用的web框架是express,所以对express框架进行了深入的了解,前段时间写了篇关于express路由的文章,但是在那篇文章中貌似少了一个很重要的内容,就 ...
- nodejs学习(二) ---- express中使用模板引擎jade
系列教程,上一节教程 express+nodejs快速创建一个项目 在创建一个项目后,views目录下的文件后缀为 .jade . 打开 index.jade,具体内容如下图(忽略 header.j ...
- Node+Express中请求和响应对象
在用 Express 构建 Web 服务器时,大部分工作都是从请求对象开始,到响应对象终止. url的组成: 协议协议确定如何传输请求.我们主要是处理 http 和 https.其他常见的协议还有 f ...
- SQL Server 2005 sa登录失败。已成功与服务器建立连接 但是在登录过程中发生错误。 provider 共享内存提供程序 error 0 管道的另一端上无任何进程。
SQL Server 2005 Express版 用户 'sa' 登录失败.该用户与可信 SQL Server 连接无关联.提示错误:已成功与服务器建立连接 但是在登录过程中发生错误. provide ...
随机推荐
- Selenium之使用PageFactory初始化pageobject
使用PageFactory初始化pageobject有什么作用呢,下面举个例子来说明 public BaiduPage baiduPage = PageFactory.initElements(dri ...
- centos运行asp.netcore的正确姿势
centos安装.netcore2.0 一切都很顺利,console app运行 dotnet run也ok 但是asp.net core app运行 dotnet run 会抛出Warn:“Unab ...
- Android 环境搭建资料及启动过程中问题汇总
一.环境搭建资料 推荐谷歌自己开发的Android Studio 工具可以从这个网址下载:http://tools.android-studio.org/,直接下载推荐的就行 二.安装 安装时最好指定 ...
- XDU 1032
#include<cstdio> typedef long long ll; ; ll feima(ll a,ll b) { ll c=; while(b) { ) c=c*a%mod; ...
- 2017 Multi-University Training Contest - Team 1 03Colorful Tree
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6035 题面: Colorful Tree Time Limit: 6000/3000 MS ( ...
- C++与C混编
C++与C混编 本案例通过实现一个简单的UDP服务器来说明C++与C的混合编程问题 C代码 通过C代码来对UDP服务器的创建,监听进行封装 udp.c文件 #include <sys/types ...
- oracle修改某字段不是必输性
执行sql: ALTER TABLE table_name MODIFY 要修改的字段名字 NULL;
- sqoop命令,mysql导入到hdfs、hbase、hive
1.测试MySQL连接 bin/sqoop list-databases --connect jdbc:mysql://192.168.1.187:3306/trade_dev --username ...
- oracle中修改表已有数据的某一列的字段类型的方法,数据备份
1.在开发过程中经常会遇到表中的某一个字段数据类型不对,比如说需要保存的数据带小数,但是在最初设计的时候是给的number(10)类型,开始保存是整数的时候满足要求,后来在保存小数的时候 会发现自动四 ...
- CSS Ul(列表样式)
CSS Ul(列表样式) CSS列表属性作用如下: 设置不同的列表项标记为有序列表 设置不同的列表项标记为无序列表 设置列表项标记为图像 一.列表 在HTML中,有两种类型的列表: 无序列表 - 列表 ...