0

I have the following node.js code:

var path = require('path');
var nodeStack = require('stack-trace');
var controller = (function () {
    function controller() {
    }
    controller.prototype.render = function (res, model, view) {
        var stack = nodeStack.get();
        var frame = stack[1];
        var functionName = frame.getFunctionName().split(/controller\./i);
        if (functionName.length < 2) {
            functionName = frame.getFunctionName().split(/(controller|\./i);
        }
        if (!view) {
            view = functionName[1];
            var dotidx = view.indexOf('.');
            if (dotidx > -1) {
                view = view.substring(0, dotidx);
            }
        }
        if (!model) {
            model = {};
        }
        var base = '';
        if (res.locals.basePath) {
            base = res.locals.basePath;
        }
        var cls = functionName[0];
        res.render(path.join(base, cls, view), model);
    };
    return controller;
})();
module.exports = controller;

The code should allow me to render a view based on the method, the matching file should be found automatically.

It works all fine, just in one case frame.getFunctionName() returns null.

The code for the subclasses look as follows:

customerController.prototype.add = function (req, res) {
    var _this = this;
    somepromise.then(function (provider) {
        return provider.getCP();
    }).then(function (cp) {
        controller.prototype.render.call(_this, res, { title: 'add customer', contactpersons: cp });
    }, function (err) {
        controller.prototype.render.call(_this, res, { title: 'add customer' });
    });
};

The one code that doesn't work.

customerController.prototype.details = function (req, res) {
    var _this = this;
    somepromise.then(function (provider) {
        return provider.getCustomerById(req.param('id'));
    }).then(function (customer) {
        _super.prototype.render.call(_this, res, { title: 'customer details', customer: customer });
    }, function (err) {
        res.status(404).send(err);
    });
};

The code works for all methods except one. Do you have an idea why?

Remarks: The code is compiled from TypeScript

Knerd
  • 1,892
  • 3
  • 28
  • 55
  • Maybe it is called from a closure? What do you see if you log the frame when getFunctionName returns null? – Kenney Oct 30 '15 at 20:04
  • @Kenney they are all the same style like the one I posted. I will check the frame and add it. – Knerd Oct 30 '15 at 20:06
  • @Kenney frame is always empty object – Knerd Oct 30 '15 at 20:13
  • Ok, that was my first thought actually - the stack size is not at least 2 (though I would expect a 'attempt to invoke function on null object' or something). Or, is it not-null but empty? Maybe log the entire stack - it seems it is called from somewhere you don't expect. – Kenney Oct 30 '15 at 20:16
  • @Kenney, I checked that and it resulted in all frames are empty object. So I am really lost by now :( – Knerd Oct 30 '15 at 20:24
  • You say it works for all methods except one: can you update the question and add an example of either? Or is it all subclasses work except one? Might be a bug in the 'stack-trace' module; there are other ways: [traceback module](http://stackoverflow.com/questions/2923858/how-to-print-a-stack-trace-in-node-js), and [Function.caller](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller) (i.e. `controller.prototype.render.caller.caller`). Other than that, I don't know.. – Kenney Oct 30 '15 at 20:37
  • One last thought - it could be called from 'top-level', perhaps via `setTimeout`. Since they are promise-based, you won't really know where they are called from, I would guess. – Kenney Oct 30 '15 at 20:48
  • @Kenney I added the code. your idea with the promises I like, I will dig into that. – Knerd Oct 30 '15 at 21:02
  • @Kenney, I just checked in Visual Studio, there I get the full callstack and that includes the correct informations. – Knerd Oct 30 '15 at 21:39

0 Answers0