Почему мои сообщения об ошибках, определенные в статическом методе схемы, не отображаются, хотя обработка ошибок, по-видимому, работает? - PullRequest
0 голосов
/ 01 мая 2019

Я определил статический метод в схеме, который определяет структуру пользовательских документов в моей базе данных mongodb. Метод .findByCredentials() проверяет, соответствуют ли предоставленные пользователем адрес электронной почты и пароль существующему пользователю и (хэшированному) паролю в базе данных. В случае, если метод user не может быть найден, выдается ошибка. То же самое делается, если пользователь найден, но bcrypt.compare() возвращает false (т. Е. Предоставленный пароль не соответствует тому, что хранится в БД). Я использую Mongoose и Express.


Проблема, с которой я столкнулся, заключается в том, что определенные мной сообщения об ошибках не передаются моему экспресс-маршруту, но оператор .catch(), который у меня есть для обработки ошибок, запускается, когда я передаю неверные учетные данные в маршрут (и, следовательно, промежуточное ПО функция). Я могу обновить res.status() и получить консольный журнал из оператора .catch(), но не могу отобразить ошибки, определенные в промежуточном программном обеспечении. Пожалуйста, прости мое ... неточное описание - я относительно новичок в бэкенде и серверах, так что я все еще пытаюсь понять, как описать то, с чем я сталкиваюсь.


Я попытался определить свойство message в сообщении об ошибке, выполнив что-то вроде:

throw new Error({ message: "Some message goes here" })

, а затем измените .catch() в моем маршруте Express следующим образом:

.catch (error) {
  res.status(400)
  res.send(error.message)
}

В своем текущем состоянии у маршрута Express есть журнал консоли, который запускается при возникновении ошибки - и журнал консоли отображается в моей консоли. Но в Почтальоне res.send(error) просто показывает пустой объект. Мое приложение Express настроено на анализ JSON (app.use(express.json())), поэтому я также попытался поэкспериментировать с анализом ошибки, но мне тоже не повезло с этим.

Экспресс-маршрут:

router.post('/users/login', async (req, res) => {
  const _email = req.body.email
  const _password = req.body.password

  try {
    const user = await User.findByCredentials(_email, _password)
    res.send(user)
  } catch (error) {
    res.status(400)
    if (error) {
      console.log("THERES An ERROR")  // THIS CONSOLE LOG IS FIRING
      res.send(error)
    }
  }
})

Промежуточное программное обеспечение (определено по довольно стереотипной пользовательской схеме)

serSchema.statics.findByCredentials = async function (email, password) {
  const user = await User.findOne({ email })

  if (!user) {
    throw new Error({ message: 'Unable to log in. Please check credentials and try again.' })
  }

  const isMatch = await bcrypt.compare(password, user.password)

  if (!isMatch) {
    throw new Error({ message: 'Unable to log in. Please check credentials and try again.' })
  }

  return user
}

Желаемый результат только для меня, чтобы получить доступ к сообщениям об ошибках, которые я определил в статическом методе. Это не важно для работы приложения - это определенно для моего собственного назидания. Опять же, насколько я могу судить, все работает с точки зрения того, что на самом деле должно делать промежуточное программное обеспечение - что возвращает пользовательский документ из БД, когда предоставленный адрес электронной почты и пароль соответствуют тому, что хранится в базе данных. У меня просто нет сообщений об ошибках, и на данный момент я хочу видеть, является ли указанный адрес электронной почты или пароль неправильным (хотя я понимаю, что это может представлять угрозу безопасности в реальном приложении).

1 Ответ

0 голосов
/ 01 мая 2019

Итак, один из возможных способов, который я нашел, находится здесь: https://humanwhocodes.com/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

(Из блога:)

function MyError(message){
    this.message = message;
}

MyError.prototype = new Error();

И в моем конкретном случае, как показано в вопросе выше:

userSchema.statics.findByCredentials = async function (email, password) {
  const user = await User.findOne({ email })
  function myError(message) {
    this.message = message
  }

  myError.prototype = new Error()

  if (!user) {
    console.log('Provide a user, you doofus')
    throw new myError('Unable to log in. Please check credentials and try again.')
  }

  const isMatch = await bcrypt.compare(password, user.password)

  if (!isMatch) {
    console.log('Password does not match, learn how to type')
    throw new Error('Unable to log in. Please check credentials and try again.')
  }

  return user
}
...