由“RangeError: Invalid status code: 0”错误所引发的思考

栏目: Node.js · 发布时间: 5年前

内容简介:最近发现一个基于网站的源码中有专门针对错误处理的中间件,经过精简之后的代码如下:乍一看,这里的status code不太可能为0,因为无论err.code的值为字符串0还是数字0,最终都会被赋值为500。除非err.code的原始值是一个不能隐式转换成数字的字符串。为了进行验证,我们写了如下代码:

最近发现一个基于 Node.js 平台上的 Express 框架运行的Web网站经常报这样一个错误:

RangeError: Invalid status code: 0

网站的源码中有专门针对错误处理的中间件,经过精简之后的代码如下:

module.exports = function (err, req, res, next) {
  var _code = err.code || 500;
  if (_code < 100 || _code >= 600) {
    _code = 500;
  }
  var _finalErr = {statusCode: -1, message: '500 - 服务器内部错误', code: _code, err: err, error: true};

  res.status(_code);
  if (!res.headersSent) {
      res.json(_finalErr);
  }

  if (err) {
    next(err);
  }
};

乍一看,这里的status code不太可能为0,因为无论err.code的值为字符串0还是数字0,最终都会被赋值为500。除非err.code的原始值是一个不能隐式转换成数字的字符串。为了进行验证,我们写了如下代码:

var _err = new Error();
_err.code = "illegal http status code";
throw _err;

启动WebStorm进入调试模式,果然复现了本文开头给出的那个错误。

由“RangeError: Invalid status code: 0”错误所引发的思考

那么问题来了,为什么给定的http status code是一个字符串,错误提示却显示这里的status code是0呢?为了搞清楚其中的原因,我们根据错误堆栈一层层查找源码。该错误的最终出处是在 Node.js源码 的_http_server.js文件的writeHead函数中,核心部分的代码如下:

statusCode |= 0;
if (statusCode < 100 || statusCode > 999)
  throw new RangeError(`Invalid status code: ${statusCode}`);

if (common._checkInvalidHeaderChar(this.statusMessage))
  throw new Error('Invalid character in statusMessage.');

这里使用了javascript中的按位或运算符:| 。其目的是将所有非数字的statusCode都默认转换成0。可以参考以下两篇文章中的描述来理解javascript中的位运算符:

http://www.w3school.com.cn/js/pro_js_operators_bitwise.asp

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR

值得注意的是,当参与计算的值不能隐式转换成数字时,得到的结果为0,可以参考上面第二篇文章中给出的一些实际例子。

在实际应用中,巧妙使用位运算符,可以非常方便地实现我们想要的效果,例如,判断一个给定的数值是否为偶数、找出给定数值最接近的偶数、判断一个字符串是否包含在另一个字符串中等等。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深度探索C++对象模型(影印版)

深度探索C++对象模型(影印版)

Stanley B. Lippman / 中国电力出版社 / 2003-8-1 / 42.00

本书重点介绍了C++面向对象程序设计的底层机制,包括结构式语意、暂时性对象的生成、封装、继承和虚拟——虚拟函数和虚拟继承。书中向你表明:理解底层实现模型,可以极大地提高你的编码效率。Lippman澄清了那些关于C++系统开销与复杂性的各种错误信息和猜测,指出了其中某些成本和利益交换确实存在。他在书中详述了各种实现模型,指出了它们的发展方向以及促使其发展的根本原因。本书涵盖了C++对象模型的语意暗示......一起来看看 《深度探索C++对象模型(影印版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具