jerrygarciuh
jerrygarciuh

Reputation: 22018

node.js - Express 4.* routes use root not local directory

I am a complete newb to node.js and am working my way through an outdated and half-broken course at udemy.com.

In previous lessons I have successfully gotten content delivered via routes like

app.get('/vegetables',function(req,res) {
    res.render('vegetables',{vegetables:vegetables});
})

In the current lesson I am seeing

Error: EPERM: operation not permitted, open 'C:\members' at Error (native)

And I can't see why. The app starts as expected, throws no warnings or errors, and __dirname contains value I would expect but every route is interpreted as being in local root C:.

What am I doing wrong?

var express = require('express'),
    path = require('path'),
    app = express(),
    bodyParser = require('body-parser'),
    logger = require('express-logger'),
    port = 9000,
    MongoClient = require('mongodb').MongoClient;


app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(logger);

app.use(express.static(__dirname + '/public'));     //establishes static file server on public dir

app.set('view engine', 'ejs');

MongoClient.connect('mongodb://127.0.0.1:27017/myExample',function(err,db) {
    if(err) throw err;
    var collection = db.collection('members');

    var index = function(req,res) {
        /*render the index view, and pass it members*/
        collection.find().toArray(function(err,members) {
            res.render('index',{members:members});
        });
    };
    var addMember = function(req,res) {
        collection.insert(req.body,function(err,docs) {
            console.log(docs);
            res.redirect('/members')
        });
    };

    app.get('/members',index);              //list all members
    app.post('/members',addMember);         //add a new member

    app.listen(port);
    console.log('server on %s',port);
    console.log(__dirname );
});


process.on('uncaughtException',function(e) {
    throw e;
});

Upvotes: 0

Views: 114

Answers (1)

curtwphillips
curtwphillips

Reputation: 5811

Logger needs a path like:

app.use(logger({path: "path/filename.txt"}));

Update

Is there some better way for me to have found this out?

You can be sure that no lines run after the line that is causing the error. console.log will work or a function to log line numbers like this:

function logLineNumber() {
    var orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack) {
        return stack;
    };
    var err = new Error;
    Error.captureStackTrace(err, arguments.callee);
    var stack = err.stack;
    Error.prepareStackTrace = orig;
    console.log('Ran line: ',stack[0].getLineNumber());
}

Use that function in express like this:

app.use(function (req, res, next) {
  logLineNumber();
  next();
});

Then you could strategically place this snippet in your code as a sanity check to know for sure that the error is after the last line number that gets logged in the console:

var express = require('express'),
    app = express(),
    path = require('path'),
    bodyParser = require('body-parser'),
    logger = require('express-logger'),
    port = 9000;

app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(function (req, res, next) {
  logLineNumber();
  next();
});


app.use(logger);

app.use(function (req, res, next) {
  logLineNumber();
  next();
});

app.use(function (req, res, next) {
  logLineNumber();
  next();
});

app.use(function (req, res, next) {
  logLineNumber();
  next();
});

app.use(express.static(__dirname + '/public'));     //establishes static file server on public dir


app.set('view engine', 'ejs');


var index = function (req,res) {
    // render the index view, and pass it members
    console.log('ran index!');
    res.render('index');
};

var redir = function (req,res) {
    // render the index view, and pass it members
    res.redirect('/');
};

app.use(function (req, res, next) {
  logLineNumber();
  next();
});

app.get('/',index);              //list all members

app.get('/redir',redir);         //add a new member

app.listen(port);
console.log('server on %s',port);
console.log(__dirname );



process.on('uncaughtException',function(e) {
    throw e;
});

function logLineNumber() {
    var orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack) {
        return stack;
    };
    var err = new Error;
    Error.captureStackTrace(err, arguments.callee);
    var stack = err.stack;
    Error.prepareStackTrace = orig;
    console.log('Ran line: ',stack[0].getLineNumber());
}

When I run the above, and go to localhost:9000, I get console output of:

Ran line:  13
/Users/phillipsc/code/node/trash/stackoverflow/redirectRoot/index.js:71
    throw e;
    ^

Error: EISDIR: illegal operation on a directory, open '/'
    at Error (native)

Up to line 13 was ok since it logged 'Ran line: 13'. The error must occur after line 13 and before the next call to logLineNumber at line 20, which narrows it down to app.use(logger).

After fixing the logger, the console will output:

Ran line:  13
Ran line:  21
Ran line:  26
Ran line:  31
Ran line:  53
ran index!

Also the code below can be helpful, although it does not help with the EISDIR error specifically.

Getting bigger stack traces:

Error.stackTraceLimit = Infinity;

Printing the stack in your error handler:

console.error(e.stack);

Upvotes: 1

Related Questions