What could be the reason for my error messages not displaying when I have defined them on a static method in the schema, despite the error handling seeming to

I have created a static method in my schema that defines the User document structure in my MongoDB database. This method, .findByCredentials(), is used to verify if a user-provided email and password match an existing user and hashed password in the database. If the user cannot be found by the method, an error is thrown. Similarly, if a user is found but the bcrypt.compare() function returns false (indicating a mismatched password), an error is thrown. I am implementing this using Mongoose and Express.


The issue I am encountering is that the error messages I have defined are not being passed to my Express route, although the .catch() statement is triggered when incorrect credentials are passed to the route (and subsequently to the middleware function). While I can update the res.status() and obtain a console log from the .catch() statement, I am unable to display the errors I set in the middleware. Please pardon my vague explanation, as I am still learning about backend development and server operations.


I have attempted to set the message property on the Error object like so:

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

and then adjusted the .catch() in my Express route as follows:

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

Currently, the Express route has a console log that triggers in the presence of an error, and I can see it in the console. However, when I check Postman, the res.send(error) displays an empty object. While my Express application is configured to parse JSON (app.use(express.json())), I have also tried various methods to parse the error without success.

Express Route:

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("THERE IS AN ERROR") // THIS CONSOLE LOG TRIGGERS
      res.send(error)
    }
  }
})

Middleware (defined in a typical User schema)

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 your credentials and try again.' })
  }

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

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

  return user
}

The main goal is to access the error messages I defined in the static method. While this is not critical for the application's functionality, it is a learning point for me. As far as I can tell, the middleware is functioning as expected—returning a user document from the database when the provided email address and password match what is stored. My current focus is on retrieving error messages to identify incorrect credentials, but I acknowledge the security implications this might pose in a real-world application.

Answer №1

I stumbled upon a potential solution that could work, which I discovered here:

(Extracted from the mentioned blog post: )

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

MyError.prototype = new Error();

In the context of my issue, as illustrated in the previous question:

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
}

Answer №2

If you simply take out the await keyword from:

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

Everything should work smoothly. I encountered this issue and spent a couple of days looking for a solution, but removing await did the trick.

Answer №3

Make sure to review the password field in your model to see if it has a 'lowercase: true' property. Additionally, if you are using throw new Error('error message') in your route catch, remember to send it as JSON. For example:

res.json({error: e.message})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript - Unable to Modify Select Value with Event Listener

It's interesting how I can change the selected option in a dropdown list using JavaScript without any issues. However, when I try to do the same thing within an event listener, the option does not seem to change. Here's the HTML code: <select ...

What is the best way to pass an array as a parameter in Angular?

I have set up my routing module like this: const routes: Routes = [ { path: "engineering/:branches", component: BranchesTabsComponent }, { path: "humanities/:branches", component: BranchesTabsComponent }, ]; In the main-contin ...

What is the best way to pass default event argument alongside another argument in React?

This snippet demonstrates the function I wish to call when a certain input type is invoked: _handleOnEnterPress = (e, receiverUserId) => { if (e.keyCode === 13) { // assuming keycode 13 corresponds to 'enter' console.log("pressed ...

Developing a custom styling class using JavaScript

Looking to create a custom style class within JavaScript tags. The class would look something like this: #file-ok { background-image: url(<?php echo json.get('filename'); ?>); } Essentially, the value returned from the PHP file (json ...

CSS / JavaScript Navigation Menu overshadowing Flash content in Firefox

On my website, I have a drop-down menu that was created using CSS and JavaScript. This menu drops down over a Flash animation. Interestingly, in Internet Explorer 6 and 7, the drop-down menus successfully appear over the Flash animation. However, in Mozill ...

Exploring the concept of JSON within node.js

As I work on creating an Alexa skill using node.js, I'm facing a challenge in defining a JSON element. Specifically, I need to gather all the titles from a news API and include them as variables in my code. Although I have successfully logged the titl ...

Executing a Python function on a server from a local machine with the help of AngularJS

I am encountering an issue with calling a python function using an angularjs $http request. The python function I have on the server looks like this: import cgi, cgitb data= cgi.FieldStorage() name = data.getvalue("name"); age = data.getvalue("age"); def ...

Passing an empty object in axios with Vue.js

When sending an object from this.productDetails in an axios.post() request, I noticed that the object appears empty when inspected in the browser's network tab. Here's the Axios call: async addProduct(){ console.log('pro ...

Obtaining a compressed file via a specified route in an express API and react interface

Feeling completely bewildered at this point. I've had some wins and losses, but can't seem to get this to work. Essentially, I'm creating a zip file stored in a folder structure based on uploadRequestIds - all good so far. Still new to Node, ...

MongoDB's conditional aggregation function allows users to manipulate and aggregate data based

My mongodb contains data like this: { "_id": "a", "reply": "<", "criterion": "story" }, { "_id": "b", "reply": "<", "criterion": "story" }, { "_id": "c", "reply": ">", "criterion": "story" } What I need is the following result: ...

AJAX throws an error when a function is used with a variable

My knowledge of jQuery and Javascript is quite limited, and I prefer not to work with them extensively. However, I always encounter an error that I can't seem to troubleshoot. Below is my code for ajax / javascript: function eintragen(id){ $.post( ...

Child component in VueJs is undergoing a situation where the variable is found to be

Whenever an event is triggered, a function is called to populate a variable and open a modal from a child component. However, in the modal, the new variable appears empty initially. If I close and then reopen the modal, the data finally loads. I have atte ...

What is the best way to manage the browser tab close event specifically in Angular, without it affecting a refresh?

I am trying to delete user cookies when the browser tab is closed. Is this achievable? Can I capture the browser tab close event without affecting refreshing? If I attempt to use beforeunload or unload events, the function gets triggered when the user ref ...

What's the best way to dynamically filter an array with a mix of different object structures?

Within my data, I have 6 different types of objects (some with double nested arrays), with varying numbers of entries, as long as each entry is unique. These objects do not possess a consistent unique identifier (one is applied on submission in the backen ...

Employing setInterval() without clearing previously triggered events

Can someone clarify the distinction between these two functions: function displayTime(){ var current = new Date(); var hours = current.getHours(); var minutes = current.getMinutes(); var seconds = current.getSeconds(); ...

Storing segments of URL data for future use in React applications

Is there a way to extract information from a URL? I wish to utilize the appended details in this URL http://localhost:3000/transaction?transactionId=72U8ALPE within a fetch API. My goal is to retrieve the value 72U8ALPE and store it either in a state var ...

Sending an array as JSON data to PHP using the $.ajax post method. The $_POST array is

After spending a considerable amount of time on this, I'm still struggling to figure out what I'm doing wrong. I'm having difficulty retrieving the data in the PHP file. I've made multiple calls to "copy" to populate the "result" arr ...

Inquiries regarding the distinctive key and component framework of Ant Design

Currently, I am in the midst of a project utilizing react, next.js, and antd. However, an error message has popped up stating: Warning: Each child in a list should have a unique "key" prop. This issue precisely stems from the absence of a uniqu ...

Adjust the speed of the remaining divs below to move up when one is deleted using Ajax and jQuery

My div elements are arranged from top to bottom, and when one selected div is removed or faded out, all other divs below it shift up suddenly to fill the gap. While this behavior is functional, I would prefer to slow down the movement of the divs shifting ...

Click on the next tab within the ExtJS tab menu

I am looking to deactivate a tab and if it happens to be active, I want the system to automatically switch to the next tab. I attempted myPanel.tab.disable(); if(myPanel.tab.active) myPanel.NextSibling().tab.setActive(); and myPanel.tab.disable(); ...