【问题标题】:Console.log(err) is crashing my websiteConsole.log(err) 使我的网站崩溃
【发布时间】:2018-12-11 22:01:14
【问题描述】:

我目前是一名学习使用 Node.js 进行 Web 开发的学生。我最近正在审查 RESTful 路由。我正在建立一个博客网站来做到这一点。我正在设置一个路由来显示一个特定的博客“/blogs/:id”,它可以让你看到一个博客的所有内容。路线如下:

app.get("/blogs/:id", function(req, res){
    blog.findById(req.params.id, function(err, blog){
        if(err){
            console.log(err)
        } else{
            res.render("show", {body: blog});
        }
    })
})

当我使用浏览器访问路由时,它会永远加载,并且我在终端中收到以下错误:

{ CastError: Cast to ObjectId failed for value "app.css" at path "_id" for model "blog"
    at MongooseError.CastError (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/error/cast.js:29:11)
    at ObjectId.cast (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/schema/objectid.js:158:13)
    at ObjectId.SchemaType.applySetters (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/schematype.js:724:12)
    at ObjectId.SchemaType._castForQuery (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/schematype.js:1113:15)
    at ObjectId.SchemaType.castForQuery (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/schematype.js:1103:15)
    at ObjectId.SchemaType.castForQueryWrapper (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/schematype.js:1082:15)
    at cast (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/cast.js:303:32)
    at Query.cast (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/query.js:3355:12)
    at Query._castConditions (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/query.js:1327:10)
    at Query._findOne (/home/ubuntu/workspace/RESTful/node_modules/mongoose/lib/query.js:1552:8)
    at process.nextTick (/home/ubuntu/workspace/RESTful/node_modules/kareem/index.js:333:33)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  message: 'Cast to ObjectId failed for value "app.css" at path "_id" for model "blog"',
  name: 'CastError',
  stringValue: '"app.css"',
  kind: 'ObjectId',
  value: 'app.css',
  path: '_id',
  reason: undefined,
  model: 
   { [Function: model]
     hooks: Kareem { _pres: [Object], _posts: [Object] },
     base: 
      Mongoose {
        connections: [Object],
        models: [Object],
        modelSchemas: [Object],
        options: [Object],
        _pluralize: [Function: pluralize],
        plugins: [Object] },
     modelName: 'blog',
     model: [Function: model],
     db: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        options: null,
        otherDbs: [],
        relatedDbs: {},
        states: [Object],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: false,
        _connectionOptions: [Object],
        client: [Object],
        name: 'restful_routing_revision',
        '$initialConnection': [Object],
        db: [Object] },
     discriminators: undefined,
     '$appliedMethods': true,
     '$appliedHooks': true,
     schema: 
      Schema {
        obj: [Object],
        paths: [Object],
        aliases: {},
        subpaths: {},
        virtuals: [Object],
        singleNestedPaths: {},
        nested: {},
        inherits: {},
        callQueue: [],
        _indexes: [],
        methods: {},
        methodOptions: {},
        statics: {},
        tree: [Object],
        query: {},
        childSchemas: [],
        plugins: [Object],
        s: [Object],
        _userProvidedOptions: {},
        options: [Object],
        '$globalPluginsApplied': true,
        _requiredpaths: [] },
     collection: 
      NativeCollection {
        collection: [Object],
        opts: [Object],
        name: 'blogs',
        collectionName: 'blogs',
        conn: [Object],
        queue: [],
        buffer: false,
        emitter: [Object] },
     Query: { [Function] base: [Object] },
     '$__insertMany': [Function],
     '$init': Promise { [Object], catch: [Function] } } }

但由于某种原因,当我将回调更改为以下内容时:

app.get("/blogs/:id", function(req, res){
        blog.findById(req.params.id, function(err, blog){
            if(err){
                res.redirect("/")
            } else{
                res.render("show", {body: blog});
            }
        })
    })

该网站运行良好。我还尝试在保留console.log(err) 的同时从show.ejs(访问路由时呈现的文件)中删除标题,它也解决了这个问题。我尝试删除标题,因为标题包含链接我在错误中提到的 app.css 文件的标签。我想知道 console.log(err) 的 css 文件有什么问题。 p.s.我使用 Express 作为路由,使用 mongoose 访问 MongoDB 数据库。 “博客”是博客数组。如果你想看看我的 show.ejs 文件,这里是:

<% include partials/header %>

<h1><%= body.title%></h1>
<img src="<%=body.image%>">
<p><%=body.body%></p>
<div><%=body.created%></div>

<% include partials/footer %>

如果你想看一下 app.css 文件,这里是:

img{
    max-width: 600px;
    width: 600px;
}

如果你想看看 header.ejs 文件,这里是:

<!DOCTYPE html>
<html>
    <head>
        <title>Blogs Website</title>
        <link rel="stylesheet" type="text/css" href="app.css">
    </head>
    <body>

这是完整的 app.js 文件(包含路由的文件):

var express = require("express"),
    app = express(),
    mongo = require("mongoose"),
    bodyParser = require("body-parser"),
    expressSanitizer = require("express-sanitizer"),
    methodOverride = require("method-override");

mongo.connect("mongodb://localhost/restful_routing_revision");
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressSanitizer());
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(methodOverride('_method'));

var blogSchema = new mongo.Schema({
    title: String,
    body: String,
    image: String,
    created: {type: Date, default: Date.now} 
});

var blog = mongo.model("blog", blogSchema);


app.get("/", function(req, res){
    res.render("landing");
});

app.get("/blogs", function(req, res){
    blog.find({}, function(err, body){
        if(err){
            console.log(err)
        }else{
            res.render("index", {blogs: body})
        }
    })
})

app.get("/dogs/new", function(req, res){
    res.render("new");
})

app.post("/dogs", function(req, res){
    var blogBody = req.body.blog;
    blog.create(blogBody, function(err, body){
        if(err){
            console.log(err)
        }else{
            res.redirect("/blogs")
        }
    })
})

app.get("/blogs/:id", function(req, res){
    blog.findById(req.params.id, function(err, blog){
        if(err){
            // res.redirect("/")
            console.log(err)
        } else{
            res.render("show", {body: blog});
        }
    })
})

// blog.findById(req.params.id, function(err, blog){
//       if(err){
//           res.redirect("/");
//       } else {
//           res.render("show", {body: blog});
//       }
//   });
// });

app.listen(process.env.PORT, process.env.IP, function(){
    console.log("The Server has Started!!!!");
})

上面有很多我打算稍后使用的 npm 包。而且我知道博客架构的格式不正确。我还尝试同时执行console.log(err)res.redirect("/"),我到达显示页面但仍然遇到相同的错误。

【问题讨论】:

  • 要完整回答您的问题,我需要查看“部分/标题”文件。浏览器中的“它永远加载”问题是因为您 必须 在每个端点都有 res.[something],即使您遇到错误也是如此。如果您发布头文件,可以在答案中提供更多详细信息,但这可能足以让您对其进行排序。
  • 这里是头文件: 博客网站
  • 可以分享一下你路由器下的代码/blogs/:id。正如上面提到的@HenryMueller,永远加载就是因为这个。错误似乎是因为您的代码和猫鼬模型之间的映射不匹配。
  • @eduPeeth 我刚刚更新了帖子,现在它包含了包含路由的文件的所有代码
  • @HenryMueller 我刚刚用你需要的信息更新了帖子。

标签: node.js database rest routes console.log


【解决方案1】:

你必须把这一行放在最后

在 app.js 文件中 剪下这一行并粘贴到最后:

app.use(express.static("public"));

【讨论】:

    【解决方案2】:

    只需使用绝对路径/style.css 而不是相对路径style.css

    说明:

    您正在使用app.use(express.static("public"));,这将使路由app.get("/blogs/:id", function(req, res){...});在触发时尝试在您的html链接标签中呈现style.css,因为它符合/blogs/style.css的路由路径,因为您的公共folder在与blogs 相同级别,因此通过将/ 放在style.css 前面使其成为绝对路径,因此执行将从种子开始路径,而不是从blogs 继续向下。

    另一个解决方案是通过实际为它创建一个路由来处理触发路由blogs/style.css,如下所示:

    app.get('/campgrounds/app.css', function(req, res) {
        break;
    });
    

    如果触发,请确保将其放在要首先执行的路由 app.get("/blogs/:id", function(req, res){...}); 之前。

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      关于 CastError,我不知道底层 ejs 代码中发生了什么导致它尝试使用 css 文件名运行 Mongo 查询,但这篇文章解释了如何修复你的语法(阅读答案的 cmets关于使用 css 名称的相对路径):

      NodeJS error when rendering page:Cast to ObjectId failed for value "styles.css" at path "_id"

      我认为这将消除端点中的错误。

      关于服务器崩溃的标题问题和观察结果:

      当我使用浏览器访问路由时,它会永远加载

      是因为当您收到错误时,端点不会向客户端发出响应。所有端点都需要以某种方式响应客户端。在您的情况下,记录在案的1 建议是接下来调用 Express 中间件函数:

      blog.findById(req.params.id, function(err, blog){
          if(err){
              console.log(err);
              next(err);
          } else{
      

      下一个函数会将错误结果返回给客户端浏览器。您需要使用 next 因为 Mongoose 模型的 .find 函数是异步的,Expresses next 函数旨在正确处理此问题。

      另外一个细节,从您发布的内容来看,您的 Express 服务器很可能没有崩溃。它正在记录带有错误的控制台消息,就像您询问的那样,然后继续等待新请求(将错误记录到控制台是完全可以的!)。如果它崩溃了,您可能会在浏览器中收到 500 错误页面,并且节点进程将终止。我提到这一点是希望对未来的调试有所帮助。我认为,如果您搜索过端点未返回的客户端问题,您可能会找到一个关于永不返回客户端的端点的现有答案(这是开始时遇到的常见问题)。希望对您有所帮助!

      Express Error Handling Doc

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-13
        • 1970-01-01
        相关资源
        最近更新 更多