ReactJS + MongoDB + NodeJS / ExpressJS:什么是process.nextTick(function(){throw err;});?

时间:2016-10-13 19:33:20

标签: javascript node.js mongodb express reactjs

在我的ReactJS项目中,我目前正在使用NodeJS和ExpressJS运行服务器,并使用MongoClient连接到MongoDB。我有一个登录API端点设置,接受用户的用户名和密码的请求。如果找不到用户,应该捕获错误并回复错误(status(500))到前端。

但是不是用json错误响应前端,服务器就崩溃了。我已经尽力找出原因,但仍然没有运气。

如何修复以下错误?任何指导或见解都将受到高度赞赏,并将提出并接受答案。

我故意使用数据库中不存在的用户名和密码({ username: 'iopsert', password: 'vser'})发出请求。

这是登录端点:

//login endpoint
app.post('/api/login/', function(req, res) {
  console.log('Req body in login ', req.body)

  console.log('THIS IS WHAT WAS PASSED IN+++++', req._id)

  db.collection('users').findOne({username: req.body.username}, function(err, user) {
    console.log('User found ')

    if(err) {
      console.log('THIS IS ERROR RESPONSE')
      // Would like to send this json as an error response to the front-end 
      res.status(500).send({
        error: 'This is error response',
        success: false,
      })
    }

    if(user.password === req.body.password) {
      console.log('Username and password are correct')
      res.status(500).send({
        username: req.body.username,
        success: true,
        user: user,
      })
    } else {
      res.status(500).send({
        error: 'Credentials are wrong',
        success: false,
      })
    }
  })

这是终端错误日志:

Req body in login  { username: 'iopsert', password: 'vset' }
THIS IS WHAT WAS PASSED IN+++++ undefined
User found 
/Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
    process.nextTick(function() { throw err; });
                                  ^

TypeError: Cannot read property 'password' of null
    at /Users/John/practice-project/server/server.js:58:12
    at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
    at /Users/John/practice-project/node_modules/mongodb/lib/collection.js:1395:5
    at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
    at /Users/John/practice-project/node_modules/mongodb/lib/cursor.js:675:5
    at handleCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:165:5)
    at setCursorNotified (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:505:3)
    at /Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:578:16
    at queryCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:226:18)
    at /Users/John/practice-project/node_modules/mongodb-core/lib/connection/pool.js:430:18

/Users/John/practice-project/node_modules/mongodb/lib/utils.js:98指的是以下内容:

var handleCallback = function(callback, err, value1, value2) {
  try {
    if(callback == null) return;
    if(value2) return callback(err, value1, value2);
    return callback(err, value1);
  } catch(err) {
    process.nextTick(function() { throw err; });
    return false;
  }

  return true;
}

编辑

以下是导入服务器的所有内容:

"use strict"

var express = require('express');
var path = require('path');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var bodyParser = require('body-parser');
var MongoClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectID;
const jwt = require('jsonwebtoken')

var app = express();
var db;

var compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));

app.use(webpackHotMiddleware(compiler));

app.use(express.static('dist'));

app.use(bodyParser.json());

这就是请求的发生方式和错误:

  loginUser(creds) {
    var request = {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(creds),
    }

    fetch(`http://localhost:3000/api/login`, request)
    .then(res => res.json())
    .then(user => {
      console.log(user);
      console.log('Successful')
    })
    .catch(err => {
      console.log('Error is', err)
    })
  },

1 个答案:

答案 0 :(得分:1)

在我看来,错误是在这一行引发的,因为user未定义。

if(user.password === req.body.password) {...}

更加努力地查看您的控制台声明。

1. Req body in login  { username: 'iopsert', password: 'vset' }
2. THIS IS WHAT WAS PASSED IN+++++ undefined
3. User found 
4. /Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
5. process.nextTick(function() { throw err; });
                              ^
6. TypeError: Cannot read property 'password' of null
7. at /Users/John/practice-project/server/server.js:58:12

第2行显示req._id为undefined

在您检查是否存在错误或用户是否确实存在之前,会打印您的User found声明,因此它并不代表实际存在用户。

第6行显示错误正在抛出,因为您正试图从空对象中读取password的属性。

我建议您修改登录逻辑,使其看起来更像这样:

//login endpoint
app.post('/api/login/', function(req, res) {
  console.log('Performing login with req.body=');
  console.log(JSON.stringify(req.body, null, 4));

  // check for username
  if (!req.body.username) {
    return res.status(401).send({message: 'No username'});
  }

  // find user with username
  db.collection('users').findOne({username: req.body.username}, function(err, user) {

    // handle error
    if(err) {
      console.log('Error finding user.');
      return res.status(500).send({message: 'Error finding user.'});
    }

    // check for user
    if (!user) {
      console.log('No user.');
      return res.status(500).send({message: 'No user.'});
    }
    console.log('User found.');

    // check password
    if(user.password !== req.body.password) {
      console.log('Wrong password.');
      return res.status(401).send({message: 'Wrong password.'});
    }

    // return user info
    return res.status(200).send(user);
  });

最后的一些想法:

  • 确保处理错误(如果存在)并在继续之前检查user是否存在。
  • 始终在return语句中包含return res.status(...).send(...),否则后续代码将会执行。
  • 将密码保存为简单字符串通常不是一个好主意。努力加密它们。请查看passportbcrypt

希望这有帮助。