最近發現一個基於Node.js平臺上的Express框架運行的Web網站常常報這樣一個錯誤:javascript
RangeError: Invalid status code: 0
網站的源碼中有專門針對錯誤處理的中間件,通過精簡以後的代碼以下:java
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的原始值是一個不能隱式轉換成數字的字符串。爲了進行驗證,咱們寫了以下代碼:node
var _err = new Error(); _err.code = "illegal http status code"; throw _err;
啓動WebStorm進入調試模式,果真復現了本文開頭給出的那個錯誤。express
那麼問題來了,爲何給定的http status code是一個字符串,錯誤提示卻顯示這裏的status code是0呢?爲了搞清楚其中的緣由,咱們根據錯誤堆棧一層層查找源碼。該錯誤的最終出處是在Node.js源碼的_http_server.js文件的writeHead函數中,核心部分的代碼以下:json
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框架
值得注意的是,當參與計算的值不能隱式轉換成數字時,獲得的結果爲0,能夠參考上面第二篇文章中給出的一些實際例子。網站
在實際應用中,巧妙使用位運算符,能夠很是方便地實現咱們想要的效果,例如,判斷一個給定的數值是否爲偶數、找出給定數值最接近的偶數、判斷一個字符串是否包含在另外一個字符串中等等。this