Issue
I’m trying to throw some custom error classes from mongoose callbacks.
Here is a simple code
const Restaurant = require('../models/Restaurant')
const { InternalServerError, UnauthorizedError } = require('../errors/errors')
const checkRestaurantAuthorization = async (token) => {
const restaurant = Restaurant.findOne({ 'token': token }, function (error, result) {
if (error) throw new InternalServerError()
else if (!result) throw new UnauthorizedError()
else return token
})
}
In my code checkRestaurantAuthorization
is called by a simple middleware like
const restaurantMidlleware = async (req, res, next) => {
console.log('Request Type:', req.method);
try {
token = await checkRestaurantAuthorization('invalid_token')
next()
} catch (error) {
next(error)
}
}
Now if a restaurant instance with the given token is not found, the app crashes with throw er; // Unhandled 'error' event
. From my testing it seems that executions stops when throw new UnauthorizedError()
is called and I’m unable to identify the issue.
Here is also an example of a custom defined error if it’s useful
class UnauthorizedError extends Error {
constructor(message) {
super(message)
this.name = 'Unauthorized request'
this.code = 403
Error.captureStackTrace(this, UnauthorizedError)
}
}
What am I missing?
Solution
have you tried putting your first block in ‘try-catch’ block?
The throw statement throws a user-defined exception. Execution of the current function will stop (the statements after throw won’t be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate.
you can change code to promise or async-await
another source of the problem could be the fact that your are using async and callback in one function try to omit async then use it again
And there is no point in writing ‘const restaurant =’ in
const restaurant = Restaurant.findOne
since every found restaurant will be saved in callback’s result variable
try this
function checkRestaurantAuthorization(token){
return new Promise(async(resolve, reject)=>{
try {
const restaurant = await Restaurant.findOne({ 'token': token });
if (!restaurant)
return reject(new UnauthorizedError())
else
return resolve(token)
}catch(error){
return reject(new InternalServerError())
}
})}
Even better approach would be using only async function
with try-catch
instead of returning a promise or any callback