当库包含在express中时抛出TypeError

时间:2015-11-24 22:26:12

标签: javascript node.js api express typeerror

我遇到了一个我似乎无法解决的非常奇怪的错误。在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)

1 个答案:

答案 0 :(得分:0)

解决了这个问题。简单的bug,但很难找到。我发现两个库中都存在一个名为endpoints的变量,但都没有用var声明,这意味着该变量被覆盖,因为它们都存在于javascript全局范围内。经验教训:始终检查变量范围。