Reputation: 2654
I am trying to convert my requests to async calls so that they are not blocking.
app.js
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
console.log(err);
res.status(err.status || 500);
res.json({ error: err.message });
});
route
router.get(
"/seatData/:seatNumber",
[
check("seatNumber")
.matches(/^[0-9][a-z]$/i)
.withMessage("must start with a number(0-9) and end with a letter")
],
actions.fetch_seat
);
controller
exports.fetch_seat = (req, res, next) => {
Seat.getSeatByNumber(req.params.seatNumber, (err, seat) => {
if (err) res.json(err);
else res.json(seat);
});
};
model
Seat.findSeat = function(key, value) {
return new Promise((resolve, reject) => {
const seat = file.find(r => r[key] === value);
if (!seat) {
reject({
error: true,
message: "Seat not found",
status: 404
});
}
resolve(seat);
});
/*
this.seat = file.find(obj => obj[key] === value);
return this.seat;
*/
};
Seat.getSeatByNumber = function(seatNumber, result, next) {
try {
this.seat = this.findSeat("seatNumber", seatNumber)
.then(seat => {
if (seat !== undefined && Object.keys(seat).length > 0) {
result(null, seat);
} else {
result({ error: true, message: "Seat not found" });
}
})
.catch(error => {
return;
});
} catch (error) {
console.log(error);
}
/* if (this.seat !== undefined && Object.keys(this.seat).length > 0) {
result(null, this.seat);
} else {
result({ error: true, message: "Seat not found" });
}*/
};
I have tried to follow few online guides but i cannot seem to get the error response back to express. the code within /* ... */
is the original that i am trying to convert
UPDATE
What is the difference between 1st catch and 2nd catch. also how comes my app.js does not catch the status code i returned back?
Seat.findSeat = function(key, value) {
return new Promise((resolve, reject) => {
const seat = file.find(r => r[key] === value);
if (!seat) {
reject({
error: true,
message: "Seat not found",
status: 404
});
}
resolve(seat);
});
};
Seat.getSeatByNumber = function(seatNumber, result, next) {
try {
this.seat = this.findSeat("seatNumber", seatNumber)
.then(seat => {
console.log(seat);
if (seat !== undefined && Object.keys(seat).length > 0) {
result(null, seat);
} else {
result({ error: true, message: "Seat not found" });
}
})
.catch(error => {
console.log("1st catch");
return result(error);
});
} catch (error) {
console.log("outer catch");
console.log(error);
result(error);
}
};
app.js the error does not get logged here
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
console.log('apperro' , err) // <-- does not log this
res.status(err.status || 500);
res.json({ error: err.message });
});
UPDATE 2
after adding next
gives me following error. you can pass in seatData/1T
into url within the sandbox https://codesandbox.io/s/elucidate-api-fokd8
(node:319) UnhandledPromiseRejectionWarning: TypeError: next is not a function
at Seat.getSeatByNumber (/sandbox/src/controller/appController.js:15:14)
at findSeat.then.catch.error (/sandbox/src/model/seat.js:45:16)
(node:319) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:319) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Upvotes: 0
Views: 335
Reputation: 366
It seems that what you would like is to bring back the error to your controller once it comes out of your model file right?
It seems that you have not returned the error in your 2 catch blocks inside your model file.
In your catch blocks, instead of just return
or console.log(error)
, you should use your result
object, like so: result(error);
UPDATE:
In your controller, you are using res.json()
. To let the handling of your logic falls through to the next step which is defined in your app.use
, you can try using next()
with the relevant parameters instead of res.json()
.
With res.json()
, the request simply sends a JSON response and ends there.
UPDATE 2:
exports.fetch_seat = (req, res, next) => {
Seat.getSeatByNumber(req.params.seatNumber, (err, seat) => {
if (err) next(err); // Error, pass error back to express
else res.json(seat); // No error, respond immediately
});
};
Upvotes: 1