我遇到了一个我似乎无法解决的非常奇怪的错误。在Node.js中,我有一个名为Markitable的API包装器库:
var request = require('request');
var Q = require('q');
/**
* Markit on Demand API Client
* @constructor
* @author Chandler Freeman <chandler.freeman@gmail.com>
*/
var Markitable = function() {
};
module.exports = Markitable;
endpoints = {
lookup: 'http://dev.markitondemand.com/Api/v2/Lookup',
quote: 'http://dev.markitondemand.com/Api/v2/Quote',
interactivechart: 'http://dev.markitondemand.com/Api/v2/InteractiveChart'
};
/**
* Company lookup
* @httpMethod GET
* @param {ticker} String A string containing the ticker for the stock
* @param {callback} callback (Optional) If callback is passed, than the function will use callbacks
* @promises yes By default, this function uses promises
*/
Markitable.prototype.lookup = function(ticker, callback) {
var options = {
url: endpoints.lookup,
headers: this.headers,
qs: { 'input': ticker.toUpperCase() },
method: 'GET',
json: true
};
if (!callback) {
var d = Q.defer();
request(options, function(err, httpResponse, body) {
if (err) return d.reject(err);
d.resolve(body);
});
return d.promise;
}
else
request(options, callback);
};
如您所见,它所做的只是从Markit on Demand API获取数据并返回Q promise。但是,每次我都包含
var Markitable = require('markitable');
我的代码中的任何地方的语句,当我导航到我收到的应用程序的/ route时
Failure on / route: TypeError: Cannot read property 'user' of undefined
我正在使用Express我完全不知道为什么会发生这种情况;我已多次重读源代码,检查源代码控制更改,一切,但我找不到问题的根源。只有包含库时,此行为才会持续存在;一旦我删除该声明,一切都很完美。我不明白,因为这个库的代码与我在我写的另一个库中使用的代码完全相同,第一个看起来很棒。这是我的路线文件的代码:
var User = require('../app/models/user');
var Robinhood = require('marian');
var util = require('util');
var Q = require('q');
module.exports = function(app, passport) {
// =========================================
// Table of Contents(Search by name)
//
// 1. Root
//
// =========================================
// ********************* 1. Root *********************
app.get('/', isLoggedIn, asyncCallback(function*(req, res) {
rh = new Robinhood(req.user.local.rhtoken);
var viewData = { user : req.user };
try {
// e: <Cannot read property user of undefined>
viewData.rhUser = yield rh.getUser();
viewData.rhUser.basic_info = yield rh.getBasicInfo();
viewData.rhPortfolio = yield rh.getPortfolio();
viewData.getOrders = yield rh.getOrders();
viewData.rhAccount = yield rh.getAccount();
viewData.active = { page : 'dashboard' };
res.render('main_pages/maindashboard.ejs', viewData);
}
catch(e) {
console.log("Failure on / route: " + e);
res.render('meta/500.ejs');
}
}));
};
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/login');
}
// Code originally from James Long
// http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
function asyncCallback(gen) {
return function() {
return Q.async(gen).apply(null, arguments).done();
};
}
关于为什么会出现这种奇怪行为的任何想法?我无法想象为什么导入库会影响'req'对象,但不知怎的。这可能是Express中的错误吗?
编辑:
忘记堆栈跟踪:
TypeError: Cannot read property 'user' of undefined
at Robinhood.getUser (/vagrant/StockFire/node_modules/marian/index.js:110:26)
at /vagrant/StockFire/app/routes.js:28:40
at next (native)
at Function.continuer (/vagrant/StockFire/node_modules/q/q.js:1278:45)
at /vagrant/StockFire/node_modules/q/q.js:1305:16
at /vagrant/StockFire/app/routes.js:226:29
at Layer.handle [as handle_request] (/vagrant/StockFire/node_modules/express/lib/router/layer.js:95:5)
at next (/vagrant/StockFire/node_modules/express/lib/router/route.js:131:13)
at isLoggedIn (/vagrant/StockFire/app/routes.js:217:16)
at Layer.handle [as handle_request] (/vagrant/StockFire/node_modules/express/lib/router/layer.js:95:5)
at next (/vagrant/StockFire/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/vagrant/StockFire/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/vagrant/StockFire/node_modules/express/lib/router/layer.js:95:5)
at /vagrant/StockFire/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/vagrant/StockFire/node_modules/express/lib/router/index.js:330:12)
at next (/vagrant/StockFire/node_modules/express/lib/router/index.js:271:10)
答案 0 :(得分:0)
解决了这个问题。简单的bug,但很难找到。我发现两个库中都存在一个名为endpoints
的变量,但都没有用var
声明,这意味着该变量被覆盖,因为它们都存在于javascript全局范围内。经验教训:始终检查变量范围。