Node Express ejs错误:无法在视图目录

时间:2015-06-04 18:10:27

标签: node.js mongodb express mongoose ejs

我正在用ejs和mongoose制作一个快速应用程序。

我收到此错误:

 Error: Failed to lookup view "error" in views directory "/Users/ben/Documents/csMSc/web/site/app/views"
at EventEmitter.app.render (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/application.js:555:17)
at ServerResponse.res.render (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:938:7)
at module.exports (/Users/ben/Documents/csMSc/web/site/app/app.js:94:7)
at Layer.handle_error (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/layer.js:58:5)
at trim_prefix (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:300:13)
at /Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:321:12)
at IncomingMessage.next (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:261:10)
at fn (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:933:25)
at EventEmitter.app.render (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/application.js:557:14)
at ServerResponse.res.render (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:938:7)
at app.use.res.render.message (/Users/ben/Documents/csMSc/web/site/app/app.js:83:9)
at Layer.handle_error (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/layer.js:58:5)
at trim_prefix (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:300:13)
at /Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/Users/ben/Documents/csMSsc/web/site/app/node_modules/express/lib/router/index.js:321:12)   

从两次调用到res.render(),其中传入的数据从mongoose查询返回,例如:

  if(req.query.author !== undefined) {
        var author = req.query.author;
        Post.find().where('author').equals(author).sort({ created: -1 }).limit(10).exec(function(err, authorsPosts) {
            if (err) return res.send("error");
            if(authorsPosts.length==0) {
                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: authorsPosts,
                    error: "Sorry there are no posts with that tag."
                });
            } else {
                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: authorsPosts
                });
            }
        });
    }

,另一个是相同但查询

    Post.find( { tags : { $elemMatch: { $in : tagList } } } ).limit(10).exec(function(err, taggedPosts) {

然而,我对该视图的所有其他渲染调用都工作正常,包括稍后在同一函数中的一个:

 //or just latest
    Post.find().sort({ created: 1 }).limit(10).exec(function(err, latestPosts) {
        if (err) return res.send(err);
        res.render('pages/index', {
            viewDataSignStatus: viewDataSignedIn[signedIn],
            previews: latestPosts
        });
    });

我非常确定latestPosts的格式与上面的authorsPosts完全相同。

没有调用呈现称为错误的视图。

传递给上述某些res.render('pages/index')调用的错误数据是使用自定义过滤器

传递的
//custom ejs filter, sets to default value if data not supplied
ejs.filters.get = function(obj, prop, def) {
  return obj[prop] === undefined ? def : obj[prop];
};

在app / views / pages / index.ejs文件中显示为

<p><%=: locals | get:'error','' %> </p>

我的ejs设置如下:

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs').renderFile);

继承了整个违规路线的所有可怕荣耀

router.get('/', function(req, res, next) {
    var accountController = new AccountController(User, req.session);
    console.log("here1");
    var signedIn = accountController.session.userProfileModel !== undefined ? 1 : 0;
    console.log("here2");

    //Author search
    if(req.query.author !== undefined) {
        var author = req.query.author;
        Post.find().where('author').equals(author).sort({ created: -1 }).limit(10).exec(function(err, authorsPosts) {
            if (err) return res.send("error");
            console.log("\n\nAuthorsPosts:" +authorsPosts);
            console.log("\n\authorsPosts.length: " +authorsPosts.length);
            console.log("authors post.constructor = " +authorsPosts.constructor);
            if(authorsPosts.length==0) {
                console.log("length=0");
                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: authorsPosts,
                    error: "Sorry there are no posts with that tag."
                });
            } else {
                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: authorsPosts
                });
            }
        });
    }
    //Tag search
    if(req.query.filter !== undefined) {
        var tagList = req.query.filter.constructor == Array ? req.query.filter : req.query.filter.split(",");
        Post.find( { tags : { $elemMatch: { $in : tagList } } } ).limit(10).exec(function(err, taggedPosts) {
            if (err) return res.send("error");
            console.log("\n\taggedPosts.length: " +taggedPosts.length);
            if(taggedPosts.length==0) {
                console.log("length=0");

                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: taggedPosts,
                    error: "Sorry there are no posts with that tag."
                });
            } else {
                console.log("\n\ntaggedPosts:\n\n" +taggedPosts);
                res.render('pages/index', {
                    viewDataSignStatus: viewDataSignedIn[signedIn],
                    previews: taggedPosts
                });
            }
        });
    }
    //or just latest
    Post.find().sort({ created: 1 }).limit(10).exec(function(err, latestPosts) {
        if (err) return res.send(err);
        res.render('pages/index', {
            viewDataSignStatus: viewDataSignedIn[signedIn],
            previews: latestPosts
        });
    });
});

更重要的是,它并非完全不起作用。当代码到达那些渲染调用时,它会抛出错误并且页面通常会冻结,您无法单击任何链接,然后如果我重新加载一次或两次它将起作用,并使用正确的数据呈现模板。

当我使用这些查询字符串前往'/'时,例如GET /?filter=Marc%20Behrens它会打印所有返回的帖子,然后抛出错误。

谢谢!

编辑:谢谢Alex Ford。

新错误是:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:690:11)
    at ServerResponse.header (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:700:10)
    at ServerResponse.send (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:154:12)
    at ServerResponse.json (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:240:15)
    at ServerResponse.send (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/response.js:142:21)
    at module.exports (/Users/ben/Documents/csMSc/web/site/app/app.js:100:9)
    at Layer.handle_error (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/layer.js:58:5)
    at trim_prefix (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:300:13)
    at /Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:270:7
    at Function.proto.process_params (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:321:12)
    at next (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:261:10)
    at Layer.handle_error (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/layer.js:60:5)
    at trim_prefix (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:300:13)
    at /Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:270:7
    at Function.proto.process_params (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:321:12)
    at next (/Users/ben/Documents/csMSc/web/site/app/node_modules/express/lib/router/index.js:261:10)

4 个答案:

答案 0 :(得分:2)

您遇到错误,默认快速错误处理程序正在尝试通过呈现错误视图向用户显示错误。您是否使用生成器生成初始应用程序?如果是这样,您是否从views目录中删除了错误视图?

更改默认快速错误处理程序(可能在您的app.js中),以便它只是吐出原始错误而不是尝试将其渲染到一个漂亮的小视图中,或添加它正在寻找的错误视图

express-cli生成的错误处理程序通常如下所示:

app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});

注意它正在尝试render('error'并且未能找到名为“error”的视图。使它成为错误处理程序的原因很简单,它接受4个参数,第一个是错误。 Express知道如果发现错误,那么它应该跳转到该处理程序。

就导致错误处理程序运行的实际错误而言,我不确定。您需要修复它以便错误显示错误,然后您就可以从那里进行调试。

答案 1 :(得分:2)

我对“已发送标头”错误的猜测是,即使上述if语句之一运行,您的 center: [200, 10], name: 'aaa', 代码仍在运行。如果是这种情况,那么您肯定会多次拨打// or just latestres.render。试试这个:

res.send

答案 2 :(得分:0)

我有这个错误,虽然使用了jsx引擎。我通过确保我的视图文件夹中的文件在我的情况下是正确的扩展名*.jsx来修复它。我的确只有index.js

答案 3 :(得分:0)

我没做的就是省略路线目录中的扩展名.html。

router.get('/', function(req, res, next) {
    res.render('index');                 //change from index to index.html
});

router.get('/', function(req, res, next) {
    res.render('index.html');
});