0

I am trying to have all my error messages in one file, each error is denoted by an error code, then in my functions/services, when there is an error, I call a function that takes the error code as an argument, then returns an object to the client with the error code and the respective error message from the errors.js file. as an example, a user trying to register with an email that already exists in the database, here is how I try to do it:

// userService.js -- where my register function is
const { errorThrower } = require('../../utils/errorHandlers');
...
static async registerNewUser(body) {
  const exists = await User.where({ email: body.email }).fetch();
  if(exists) {
    errorThrower('400_2');
  }
  ...
}

errorHandlers.js file:

exports.errorThrower = (errCode) => {
    throw Object.assign(new Error(errors[errorCode]), { errorCode })
}

exports.errorHandler = (err, req, res, next) => {
    if(!err.status && err.errorCode) {
      err.status = parseInt(err.errorCode.toString().substring(0, 3), 10);
    }
    
    let status, message
    if (err.status) {
      status = err.status
      message = err.message
    } else {
      status = 500;
      message = 'unexpected behavior, Kindly contact our support team!'
    }
    
    res.status(status).json({
      errorCode: err.errorCode,
      message
    })
}

errors.js

module.exports = {
    '400_1': 'JSON payload is not valid',
    '400_2': 'user already registered',
    ...
}

...
const user = require('./routes/user');
const { errorHandler } = require('../utils/errors');

...
app.use('/user' , user);
app.use(errorHandler);
...

now with this setup, when hitting the register endpoint by postman, I only get the following in the console

UnhandledPromiseRejectionWarning: Error: user already registered

could someone please tell me what am I missing here? thanks in advance!

12
  • You are not await ing the call to registerNewUser(body) ... Commented May 22, 2019 at 20:22
  • nope, I am in fact using await when calling it, this is from the userController.js exports.register = async(req, res) => await registerNewUser(req.body), so yeah thats not where the issue is, any other thoughts ? Commented May 22, 2019 at 20:28
  • Thats exactly where the issue is (probably). Where do you call that register function? Commented May 22, 2019 at 20:35
  • what exactly do you see? Commented May 22, 2019 at 20:35
  • remember, this is just a controller file, the register the gets exported here, is imported in the userRoutes.js file, so express router.post('/register', register) redirects the request to the controller, then to the userService.js! I hope you are following Commented May 22, 2019 at 20:38

1 Answer 1

1

You're not catching the error which you throw inside your errorThrower, thus getting the error UnhandledPromiseRejectionWarning. What you need to do is catch the error and pass it on the the next middleware, in order for the errorHandler-middleware to be able to actually handle the error. Something like this:

exports.register = async(req, res) => {
   try {
       await registerNewUser(req.body);
   } catch(err) {
       next(err);
   }
};

If you don't want to do this for every middleware, you could create a "base"-middleware which handles this:

const middlewareExecutor = async (req, res, next, fn) => {
    try {
        return await fn.call(fn, req, res, next);
    } catch (err) {
        next(err);
    }
};

Now you can pass your middlewares as an argument and delegate handling the error to the executor:

app.use('/user' , async (req, res, next) => middlewareExecutor(req, res, next, user));
Sign up to request clarification or add additional context in comments.

1 Comment

that worked, thank you, but it's not a very optimal solution, I need a little helper function as middleware to be applied across the application so I don't have to try and catch for every single route, any thoughts? thanks anyway)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.