ReactJS MongoDB NodeJS/ExpressJS: что такое process.nextTick(функция() { выбросить ошибку; });?

#javascript #node.js #mongodb #express #reactjs

#javascript #node.js #mongodb #выразить #reactjs

Вопрос:

В моем проекте ReactJS я в настоящее время запускаю сервер с помощью NodeJS и ExpressJS и подключаюсь к MongoDB с помощью MongoClient. У меня настроена конечная точка 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. Кажется user или req.body не определено, включили ли вы анализатор тела в свой проект.

2. @adeneo Да, пожалуйста, взгляните на редактирование в исходном сообщении. Когда я передаю запрос с именем пользователя и паролем, которые существуют, user регистрируются правильные req.body и и вводится оператор if.

Ответ №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(...) инструкции, иначе последующий код будет выполнен.
  • Обычно не рекомендуется сохранять пароли в виде простых строк. Работайте над их шифрованием. Посмотрите на паспорт или bcrypt.

Надеюсь, это поможет.

Комментарии:

1. Извините, но на самом деле req._id просто не существует, потому что запрос не передал его, поэтому просто игнорируйте его. Ошибка tick также не возникает, если пользователь действительно существует в базе данных, поэтому я предполагаю, что, когда пользователь не найден, он неправильно обрабатывает ответ об ошибке? Кроме того, когда я делаю findOne() и вводит функцию, разве это уже не означает, что имя пользователя найдено? Зачем снова проверять пользователя и не должно ли этого быть user.username ? Почему это означает by !user , потому что у этого объекта нет username and password ? Спасибо за помощь

2. Просто попробовал, но возврат ошибки фактически передается как a response из интерфейса и консоли, регистрирующей объект ({message: "No user"}) , а не перехватывается в catch() функции как error . Могу ли я что-то упустить из интерфейса, чтобы уловить в catch() функции?

3. Просто проверяю, видели ли вы мои последние комментарии. Пожалуйста, дайте мне знать.