0

I'm using mongoose to interact with db and use the errorHandler middleware to handle the exception error

The controller :

const asyncHandler = require('express-async-handler');
const Contact = require('../models/contactModel');

const getContact = asyncHandler(async (req, res) => {
  const contact = await Contact.findById(req.params.id);

  if (!contact) {
    res.status(404);
    throw new Error('Contact not found');
  }

  res.status(200).json(contact);
});

errorHandler middleware :

const { constants } = require('../constants');
const errorHandler = (err, req, res, next) => {
  const statusCode = res.statusCode ? res.statusCode : 500;

  switch (statusCode) {
    case constants.VALIDATION_ERROR:
      res.json({
        title: 'Validation failed',
        message: err.message,
        stackTrace: err.stack
      });
    case constants.UNAUTHORIZED:
      res.json({
        title: 'Unauthorized',
        message: err.message,
        stackTrace: err.stack
      });
    case constants.FORBIDDEN:
      res.json({
        title: 'Forbidden',
        message: err.message,
        stackTrace: err.stack
      });
    case constants.NOT_FOUND:
      res.json({
        title: 'Not found',
        message: err.message,
        stackTrace: err.stack
      });
    case constants.SERVER_ERROR:
      res.json({
        title: 'Server error',
        message: err.message,
        stackTrace: err.stack
      });
    default:
      console.log('No error, all is well !');
      break;
  }
};

Its working fine If the document is found, But if it doesn't get the result the error handler middleware seems to always get the default switch case instead of returning the 404 error, enter image description here

how can i solve this ?

owf
  • 245
  • 1
  • 9
  • 26

2 Answers2

1

The problem is in the id format. For example, if you have this id "64b308036b91b6c79949f82f", delete the last char and add a number, e.g., 2, everything will work fine. Good luck mate!

0

You didn't break the case clause, so it "fall-through" to the default clause. see Breaking and fall-through

A working example:

const express = require('express')
const asyncHandler = require('express-async-handler');

const app = express();

const getContact = asyncHandler(async (req, res) => {
  const contact = undefined;

  if (!contact) {
    res.status(404);
    throw new Error('Contact not found');
  }

  res.status(200).json(contact);
});

const constants = {
  NOT_FOUND: 404
}
const errorHandler = (err, req, res, next) => {
  const statusCode = res.statusCode ? res.statusCode : 500;

switch (statusCode) {
  case constants.NOT_FOUND:
    res.json({
      title: 'Not found',
      message: err.message,
      stackTrace: err.stack
    });
    break;
  default:
    console.log('No error, all is well !');
    break;
}
};

app.get('/', getContact)
app.use(errorHandler)

app.listen(3000, () => console.log('server started'))

Testing:

$ curl -X GET http://localhost:3000            
{"title":"Not found","message":"Contact not found","stackTrace":"Error: Contact not found\n    at /Users/elsa/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/76180594/app.js:11:11\n    at asyncUtilWrap (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express-async-handler/index.js:3:20)\n    at Layer.handle [as handle_request] (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)\n    at next (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/route.js:137:13)\n    at Route.dispatch (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/route.js:112:3)\n    at Layer.handle [as handle_request] (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)\n    at /Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:281:22\n    at Function.process_params (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)\n    at next (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)\n    at expressInit (/Users/elsa/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/middleware/init.js:40:5)"}%

The logs of the server:

$ node /Users/elsa/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/76180594/app.js
server started

If I remove the break statement, after access the API endpoint, the logs of server:

⚡  node /Users/elsa/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/76180594/app.js
server started
No error, all is well !
Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • still doesnt work, i even switched to if-else statement and still got the same problem, turns out the statusCode which has been sent to errorHandler was 200 which i never passed as you can see on my controller i passed 404 instead of 200 – owf May 05 '23 at 12:26
  • @owf Updated answer with a working example – Lin Du May 05 '23 at 12:53
  • according to this thread https://stackoverflow.com/questions/67246104/mongoose-defining-404-status-for-not-finding-a-document-doesnt-work turns out the problem was the parameter's char length, it should be 24 char , i tested it and it work, anyway, Thanks for your advice! – owf May 05 '23 at 13:02