Why am I setting headers twice - node.js

I am recieving this error: Cannot set headers after they are sent to the client
I take that to mean the code is attempting to set the response headers more than once. This is the code, but I cant seem to find out where the headers are being set twice.
async function createTrip(request, response) {
const { vehicleId, driverId, startedAt, expectedReturn } = request.body
let driver, vehicle
//validation
await pool.query(
'SELECT * FROM Vehicle WHERE id = $1',
[vehicleId],
(error, results) => {
if (error) {
throw `ERROR::createTrip threw an error: ${error}`
}
if (results.rowCount === 0) {
return response.send({ status: 404, message: `vehicle with id ${vehicleId} does not exist.` })
} else if (results.rows[0].in_use) {
return response.send(403).send({ status: 403, message: `vehicle with id ${vehicleId} is not available for rental` })
} else {
vehicle = results.rows[0]
}
}
)
await pool.query(
'SELECT * FROM Driver WHERE id = $1',
[driverId],
(error, results) => {
if (error) {
throw new Error(`ERROR::createTrip threw an error: ${error}`)
} else if (results.rowCount === 0) {
return response.status(404).send({ status: 404, message: `driver with id ${driverId} does not exist` })
} else {
driver = results.rows[0]
}
}
)
//event
await pool.query(
'INSERT INTO Trip (status,started_at, expected_return, driver, vehicle) VALUES ($1,$2,$3,$4,$5) RETURNING *',
['active', startedAt, expectedReturn, driverId, vehicleId],
(error, results) => {
if (error) {
throw `ERROR::createTrip threw an error: ${error}`
} else {
return response.status(200).send({ id: results.rows[0].id, status: results.rows[0].status, startedAt, expectedReturn, driver, vehicle })
}
}
)
await pool.query(
'UPDATE Vehicle SET in_use = TRUE WHERE id = $1',
[vehicleId],
(error) =>{
if(error){
throw `ERROR::createTrip threw an error: ${error}`
}
}
)
}

Your createTrip function does four queries. Each of those queries results in a response potentially being called. You should do all the processing from all the queries you need to inside a try/catch block. Then, instead of sending a response when rowCount === 0 for example, throw an error, catch it in the catch block and send the response from there.

Related

Error: DPI-1002: invalid dpiConn handle: Nodejs, Oracledb

I have the following API, the API is inserting into a table based on user selection from the client. User can select different material belonging to same experiment. In my payload, I have materials as array, experiment as string. I tried several ways to resolve my error. Following was the last try:
app.post("/insertMaterials", (req, res) => {
for (let mat of req.body["material"]) {
try {
oracledb.getConnection(
{
user: "some_user",
password: "some_pw",
connectString: "someConnStr",
},
function (err, connection) {
if (err) {
console.error("1" + err);
return;
}
connection.execute(
"INSERT INTO MATERIALS (ID, MAT_NAME, EXPR) VALUES((SELECT max(ID) + 1 FROM MATERIALS), :1, :2)",
[mat, req.body["experiment"]],
(err, result) => {
if (err) {
console.error("log " + err);
}
connection.commit();
connection.close();
}
);
}
);
} catch (error) {
console.log(error);
}
}
return res.status(200).json({
title: "SUCCESS: Materials Inserted",
});
});
I always get:
triggerUncaughtException(err, true / fromPromise /);
^
[Error: DPI-1002: invalid dpiConn handle] { errorNum: 0, offset: 0 }
Before I had a separate function of the block inside the for loop and I also tried with execeuteMany. Still same error. After trying lot other ways and reading in internet, I couldn't solve the issue. Except for finally catching uncaughtException and logging the error:
process.on('uncaughtException', (error, next) => {
let date = new Date()
errorLogStream.write(`Date: ${date}. Err: ${error.stack} \n`)
return
})
By catching this exception, my program does not break anymore and data is always inserted. But it would be great to know how and when this is raised and how this can be resolved or where if I am doing a mistake.
UPDATE
Payload example: {'material': ['F99999.7', 'J84845.4'], 'experiment': 'NA32R'}
Function:
async function addMatToExpr(exp, mat) {
let connection;
try {
connection = await oracledb.getConnection(
{
user: "some_user",
password: "some_pw",
connectString: "someConnStr",
});
result = await connection.execute("INSERT INTO MATERIALS (ID,
MAT_NAME, EXPR) VALUES((SELECT max(ID) + 1 FROM MATERIALS), :1, :2)",
[exp, mat], { autoCommit: true })
} catch (error) {
return res.status(404).json({
title: error,
});
} finally {
if (connection) {
try {
await connection.close()
} catch(error) {
console.log(error)
}
}
}
}
API:
app.post("/insertMaterials", (req, res) => {
for (let mat of req.body["materials"]) {
addMatToExpr(req.body["experiment"], mat)
}
});
Added the async/await function and the api that calls the function.
You need to 'await' the Oracle function calls so each completes before continuing. Currently the connection is being closed before the statement is executed.
See all the node-oracledb documentation and examples.
E.g.
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
result = await connection.execute(sql, binds, options);
console.dir(result, { depth: null });
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}

Rejected Promise breaks loop despite catch

I am creating a loop to create/update users using functions with built-in promises:
for (const user of usersjson.users) {
let getuser = getUser(url, okapikey, user[fieldMap.externalSystemId],
'externalSystemId'); //Check if user exists on the server
await getuser
.then(async (data) => {
if (data.users.length != 0) { //If user exists in the array
update = updateUser(url, okapikey, createduser, data.users[0].id);//Create update function
promises.push(update); //Store function in array
i++;
} else {
create = createNewUser(url, okapikey, createduser);//Create create function
promises.push(create); //Store function in array
i++;
}
}).catch((err) => {
console.error(err);
});
if (promises.length == 50 || i == usersjson.users.length) {//Run functions in batches of 50
await Promise.allSettled(promises)
.then((responses)=> {
for (const response of responses) { //For each promise response
if (response.status == 'fulfilled') { //If fulfilled
if (response.value.status == 204) {
console.log(`${response.value.status}: User ${response.value.request.path.substring(7)} was updated.`);
} else {
if (response.value.status == 201 && response.value.headers.location) {
console.log(`${response.value.status}: User ${response.value.headers['location']} was created.`);
} else {
console.log(response.value.headers.location);
}
}
} else { //Handle rejections
console.log(`There was an error with the user:${response.value}`);
}
}
}).catch((err)=> {
console.log(err);
});
promises=[]; //Empty Promise array
}
}
async function updateUser(url, token, user, userid)
{
return new Promise((resolve, reject) => {
//Create headers for put request
const options = {
method: "put",
headers: {
'x-okapi-token': token,
'x-okapi-tenant':'tenant',
'Content-type':"application/json"
}
};
//Make API get call
user.id=userid; //Adding the required field ID to the JSON
axios.put(`${url}/users/${userid}`, JSON.stringify(user), options)
.then(response => {
if (response.status == 204) {
resolve(response);
} else {
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
}
}).catch((err) => {
console.error(`Error Code: ${err.response.status}`);
if (typeof err.response.data == 'string') {
console.error(err.response.data);
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
} else if (err.response.data.errors[0].message) {
console.error(`Error Text: ${err.response.data.errors[0].message}`);
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
} else {
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
}
console.log(err.response);
});
});
};
async function createNewUser (url, token, user) {
return new Promise((resolve, reject) => {
//Create headers for put request
const options = {
headers: {
'X-Okapi-token': token,
'Content-type':"application/json"
}
};
//Make API get call
axios.post(`${url}/users`, JSON.stringify(user), options)
.then(response => {
if (response.status == 201) {
resolve(response);
} else {
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
}
}).catch((err) => {
console.error(`Error on ${user.externalSystemId}: ${err}`);
if (err.response.data && typeof err.response.data == 'string') {
console.error(err.response.data);
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
} else if (err.response.data.errors[0].message) {
console.error(`Error Text: ${err.response.data.errors[0].message}`);
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
} else {
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
}
});
});
};
const getUsers = (url,user,password) =>
{
return new Promise((resolve, reject) => {
//Create headers for POST request
const options = {
method: 'post',
headers: {
'Authorization': 'Basic '+Buffer.from(`${user}:${password}`).toString('base64')
}
}
//Make API get call
axios.get(url, options)
.then(response => {
resolve(response.data);
}).catch((err) => {
console.error(err);
reject(err);
});
});
};
The code and loop works fine when every promise is fulfilled, but once a promise is rejected, the loop breaks. I get the error message, for example:
Error on XXX: Error: Request failed with status code 422 Error Text:
User with this username already exists
node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: 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(). The promise rejected with
the reason "Error Code: 422: XXX, Error Text: User with this username
already exists, Error Status: Error: Request failed with status code
422".] { }
Looking at the code and error, I believe this comes from the "createNewUser" function.
I'm not sure why the code breaks - I added catches to all the functions, handled rejections, and added catch statements in the main body of the code, but the loop still breaks.
What I need is for the loop to continue as usual even if one function fails (I will later change the log from console.log to an actual log file).
update = updateUser(url, okapikey, createduser, data.users[0].id);//Create update function
promises.push(update); //Store function in array
create = createNewUser(url, okapikey, createduser);//Create create function
promises.push(create); //Store function in array
This is inaccurate. You are not storing functions in that array, you actually call the updateUser/createNewUser functions here and store the resulting promises in the array. Then, your loop goes on to sequentially (because of the await) do more getUser operations before actually calling Promise.allSettled on the promises array. In the meantime, some of the promises might already have been rejected without having any handlers attached to them.
This is basically the same problem as discussed in Waiting for more than one concurrent await operation and Any difference between await Promise.all() and multiple await?.
To fix it, collect actual functions that you can execute later in your array:
let functions = [];
for (const user of usersjson.users) {
i++;
try {
const data = await getUser(url, okapikey, user[fieldMap.externalSystemId], 'externalSystemId');
if (data.users.length != 0) {
functions.push(() =>
// ^^^^^
updateUser(url, okapikey, createduser, data.users[0].id)
); // Create update function and store it in array
} else {
functions.push(() =>
// ^^^^^
createNewUser(url, okapikey, createduser)
); // Create create function and store it in array
}
} catch(err) {
console.error(err);
}
if (functions.length == 50 || i == usersjson.users.length) { // in batches of 50
const promises = functions.map(fn => fn()); // Run functions
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
const responses = await Promise.allSettled(promises);
for (const response of responses) {
if (response.status == 'fulfilled') {
if (response.value.status == 204) {
console.log(`${response.value.status}: User ${response.value.request.path.substring(7)} was updated.`);
} else {
if (response.value.status == 201 && response.value.headers.location) {
console.log(`${response.value.status}: User ${response.value.headers['location']} was created.`);
} else {
console.log(response.value.headers.location);
}
}
} else {
console.log(`There was an error with the user:${response.value}`);
}
}
functions = []; // empty functions array
}
}
(I've tried to avoid awaiting any .then(…) chains)

If statement in nodejs not executing in order

Below is controller.js script. I am facing hard time to go inside if loop "if(changeUserToSellerFlag == 1)" because this if statement is executed much earlier than this if statement "if (results.Name == "Customer")". I am not sure why the order of execution is not done line by line.
const { updateUserSellerStatus } = require("./seller.model.js");
const { genSaltSync, hashSync } = require("bcrypt");
const userid = require("../auth/token_validation.js");
const {
updateUserRoleAfterSellerApproval,
getRoleName,
} = require("../users/user.service.js");
module.exports = {
sellerVerify: (req, res) => {
var sellerStatusName;
var changeUserToSellerFlag = 0; // this flag determines if user to seller update is needed or not
approvedByName = req.fullName; //get full name from token_validation.js
approvedByEmail = req.email; //get email from token_validation.js
console.log("Request body is below");
console.log(req.body); // contains body sent by postman
updateUserSellerStatus(
req.body,
approvedByName,
approvedByEmail,
(err, results) => {
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
if (!results) {
console.log(results);
return res.json({
success: 0,
message: err,
});
}
if (req.body.sellerStatus == 3) {
sellerStatusName = "Rejected";
} else if (req.body.sellerStatus == 2) {
sellerStatusName = "Completed";
} else if (req.body.sellerStatus == 1) {
sellerStatusName = "Pending";
}
//verify if user is a seller or not
if (req.userId) {
getRoleName(req.userId, (err, results) => {
console.log("check rolename gettign below");
console.log(results);
if (results.Name == "Customer") {
console.log("User is Customer");
changeUserToSellerFlag = 1;
console.log("flag is :" + changeUserToSellerFlag);
} else if (results.Name == "Seller") {
console.log("User is Seller");
changeUserToSellerFlag = 0;
}
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
});
}
console.log("see flag changed here ", changeUserToSellerFlag);
if (changeUserToSellerFlag == 1) {
console.log("i am here");
//update userrole to seller only if user is not a seller earlier
updateUserRoleAfterSellerApproval(
req.userId,
req.roleId,
(err, results) => {
console.log("result details are bwlo");
console.log(results);
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
if (!results) {
console.log(results);
return res.json({
success: 0,
message: err,
});
}
console.log("Update into UserRole Completed successfully");
},
);
} else {
console.log(
"User is already a seller and dont need to update userrole table",
);
}
console.log(sellerStatusName);
return res.status(200).json({
success: 1,
status: sellerStatusName,
});
},
);
},
};
Below is console output
Request body is below
{ sellerId: 122, sellerStatus: 2 }
see flag changed here 0
User is already a seller and dont need to update userrole table
Completed
check rolename gettign below
TextRow { Name: 'Customer', RoleId: 2 }
User is Customer
flag is :1
where "User is already a seller and dont need to update userrole table" is executed first before "flag is :1"
to me it looks as if you're treating asynchronous code as if it was synchronous. At the top of the function you are calling parts of the code that are asynchronous, like for example every database query is generally async call.
getRoleName(req.userId, (err, results) //i assume this is an async call
process will not wait for the above code to finish before proceeding forward with its execution because it is written synchronously. So next instructions that it will execute are:
console.log('see flag changed here ', changeUserToSellerFlag);//0
if(changeUserToSellerFlag == 1)//0 --> false
}else{console.log("User is already a seller and dont need to update userrole table");}//so these 3 orders are executed immediately.
after which the async call from (i assume)
getRoleName(req.userId, (err, results)
will have finished and the proper callback will be called.
as a potential solution:
I would either wait for any database call to finish before proceeding. You can use async - await call, other solutions are also usage of Promises and of course making a callback hell.
If we use callback because you are already using them it would look something like this:
updateUserSellerStatus(
req.body,
approvedByName,
approvedByEmail,
(err, results) => {
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
if (!results) {
console.log(results);
return res.json({
success: 0,
message: err,
});
}
if (req.body.sellerStatus == 3) {
sellerStatusName = "Rejected";
} else if (req.body.sellerStatus == 2) {
sellerStatusName = "Completed";
} else if (req.body.sellerStatus == 1) {
sellerStatusName = "Pending";
}
//verify if user is a seller or not
if (req.userId) {
getRoleName(req.userId, (err, results) => {
console.log('check rolename gettign below');
console.log(results);
if (results.Name == "Customer") {
console.log("User is Customer");
changeUserToSellerFlag = 1;
console.log("flag is :" + changeUserToSellerFlag);
} else if (results.Name == "Seller") {
console.log("User is Seller");
changeUserToSellerFlag = 0;
}
console.log('see flag changed here ', changeUserToSellerFlag);
if (changeUserToSellerFlag == 1) {
console.log("i am here");
//update userrole to seller only if user is not a seller earlier
updateUserRoleAfterSellerApproval(
req.userId,
req.roleId,
(err, results) => {
console.log("result details are bwlo");
console.log(results);
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
if (!results) {
console.log(results);
return res.json({
success: 0,
message: err,
});
}
console.log("Update into UserRole Completed successfully");
}
);
} else {
console.log("User is already a seller and dont need to update userrole table");
}
console.log(sellerStatusName);
return res.status(200).json({
success: 1,
status: sellerStatusName,
});
}
if (err) {
console.log(err);
return res.status(500).json({
success: 0,
message: err,
});
}
});
}
);
},
};
I just moved the code which was below the
console.log('see flag changed here ', changeUserToSellerFlag);
inside the first callback method.
I'd recommend refactoring the callback-hell asynchronicity to promises.
Happily, util.promisify in Node's util library makes it super easy to do that for functions that are callback-async.
You end up with something like this:
const { promisify } = require("util");
const { updateUserSellerStatus } = require("./seller.model.js");
const userid = require("../auth/token_validation.js");
const {
updateUserRoleAfterSellerApproval,
getRoleName,
} = require("../users/user.service.js");
const updateUserSellerStatusP = promisify(updateUserSellerStatus);
const getRoleNameP = promisify(getRoleName);
const updateUserRoleAfterSellerApprovalP = promisify(
updateUserRoleAfterSellerApproval,
);
async function sellerVerify(req) {
var sellerStatusName;
var changeUserToSellerFlag = 0; // this flag determines if user to seller update is needed or not
switch (req.body.sellerStatus) {
case 3:
sellerStatusName = "Rejected";
break;
case 2:
sellerStatusName = "Completed";
break;
case 1:
sellerStatusName = "Pending";
break;
}
const results = await updateUserSellerStatusP(
req.body,
req.fullName,
req.email,
);
if (!results) throw new Error("No results from UUSS");
//verify if user is a seller or not
if (req.userId) {
const roleName = await getRoleNameP(req.userId);
if (roleName.Name === "Customer") {
changeUserToSellerFlag = 1;
} else if (roleName.Name === "Seller") {
changeUserToSellerFlag = 0;
}
}
if (changeUserToSellerFlag) {
console.log("i am here");
//update userrole to seller only if user is not a seller earlier
const results = await updateUserRoleAfterSellerApprovalP(
req.userId,
req.roleId,
);
console.log(results);
if (!results) throw new Error("UURASP results missing");
console.log("Update into UserRole Completed successfully");
} else {
console.log(
"User is already a seller and dont need to update userrole table",
);
}
console.log(sellerStatusName);
return {
success: 1,
status: sellerStatusName,
};
}
module.exports = {
sellerVerify: async (req, res) => {
try {
const result = await sellerVerify(req);
return res.json(result);
} catch (err) {
console.error(err);
return res.status(500).json({
success: 0,
message: err,
});
}
},
};

Node Cron / Node Schedule does not always work on specific date

I need to run queries jobs at specific dates, After researching nodejs libraries for that node schedule was more recommended then node-cron because it handles better for one time jobs then for repetitive jobs.
The problem is that sometimes the job is running like it should and sometimes it not running i'm not getting any error.
Usually the cron jobs does not get executed if the selected date is longer then 2 hours and works properly if the selected date is 30 minutes or less.
I tried both node-cron and node schedule libraries, i added error handler to catch the error when cron job does not get executed but no error is thrown when the job is not getting executed.
route.js :
router.put('/preview', auth, async (req, res) => {
const auctionId = req.body.auctionId;
const auctionStartDate = req.body.auctionStartDate;
let bidEndDate = req.body.bidEndDate;
let auctionEndDate = req.body.auctionEndDate;
const chargeableWeight = req.body.chargeableWeight;
//create auction serial number if the auctions is new and not modified
await db.query(
`SELECT right(AuctionSerialNumber,length(AuctionSerialNumber)-1) as serialCount
FROM auctions
ORDER BY cast(right(AuctionSerialNumber,length(AuctionSerialNumber)-1) as unsigned) DESC
LIMIT 1`,
async (error2, results2, fields2) => {
if (error2) res.status(400).json({ errors: error2.message });
let serialCount = results2[0].serialCount;
let tempSerialNumber = parseInt(serialCount, 10);
let nextSerial = tempSerialNumber + 1;
nextSerial = 'A' + nextSerial;
await db.query(
`UPDATE fretit.auctions SET
fretit.auctions.AuctionEndDate = '${auctionEndDate}',
fretit.auctions.StartDate='${auctionStartDate}',
fretit.auctions.BidEndDate='${bidEndDate}',
fretit.auctions.AuctionSerialNumber='${nextSerial}',
fretit.auctions.AuctionState=2,
fretit.auctions.WinningBidID='000',
fretit.auctions.ChargeableWeight='${chargeableWeight}'
WHERE fretit.auctions.UID='${auctionId}'`,
(error, result, fields) => {
if (error) res.status(400).json({ errors: error.message });
}
);
//start bid end date timer
var j1 = schedule.scheduleJob(bidEndDate, async () => {
console.log('starting bid end date');
await db.query(
`SELECT auctions.AuctionState as auctionState
FROM auctions
WHERE auctions.UID='${auctionId}'
`,
async (error2, result2, fields2) => {
if (error2) res.status(400).json({ errors: error.message });
let auctionState = result2[0].auctionState;
console.log(auctionState);
//if auction state is LiveNoBids give notification and start auction end date
if (auctionState == 2) {
await db.query(
`UPDATE auctions SET
auctions.AuctionLostNotification=1,
auctions.AuctionState=4
WHERE auctions.UID='${auctionId}'
`,
(error, result, fields) => {
if (error) res.status(400).json({ errors: error.message });
var j3 = schedule.scheduleJob(auctionEndDate, async () => {
console.log(auctionEndDate);
console.log(
'this auction reached bidEndDate and does not have bids'
);
await db.query(
`SELECT auctions.AuctionState as auctionState
FROM auctions
WHERE auctions.UID='${auctionId}'
`,
async (error2, results2, fields2) => {
if (error2)
res.status(400).json({ errors: error.message });
let auctionState = results2[0].auctionState;
console.log(auctionState);
//if auction state is DueDateExceeded when auctionEndDate ends move auction state to Expired
if (auctionState == 4) {
console.log(auctionState);
await db.query(
`UPDATE auctions SET
auctions.AuctionState=7
WHERE auctions.UID='${auctionId}'
`,
(error3, result3, fields3) => {
if (error3)
res
.status(400)
.json({ errors: error.message });
}
);
}
}
);
});
}
);
//if auction state is LiveWithBids move auction state to DueDateExceeded
} else if (auctionState == 3) {
console.log(auctionState);
await db.query(
`UPDATE auctions SET
auctions.AuctionState=4,
auctions.AuctionWonNotification=1
WHERE auctions.UID='${auctionId}'
`,
(error, result, fields) => {
if (error) res.status(400).json({ errors: error.message });
//start auction end date timer
var j2 = schedule.scheduleJob(auctionEndDate, async () => {
console.log(auctionEndDate);
console.log(
'this auction reached bidEndDate and have bids'
);
await db.query(
`SELECT auctions.AuctionState as auctionState
FROM auctions
WHERE auctions.UID='${auctionId}'
`,
async (error2, result2, fields2) => {
if (error2)
res.status(400).json({ errors: error.message });
let auctionState = result2[0].auctionState;
console.log(auctionState);
//if auction state is DueDateExceeded when auctionEndDate ends move auction state to Expired
if (auctionState == 4) {
console.log(auctionState);
await db.query(
`UPDATE auctions SET
auctions.AuctionState=7
WHERE auctions.UID='${auctionId}'
`,
(error3, result3, fields3) => {
if (error3)
res
.status(400)
.json({ errors: error.message });
}
);
}
}
);
});
}
);
}
}
);
});
}
);
});
catchErrorAsync.js:
module.exports = function(handler) {
return async (req, res, next) => {
try {
await handler(req, res);
} catch (ex) {
next(ex);
}
};
};
error.js:
const winston = require('winston');
module.exports = function(err, req, res, next) {
// log error message to file
winston.error(err.message, err);
// Send a user-friendly message back to the user
res.status(500).send('Something went wrong...');
};
Why the cron jobs sometimes working and sometimes not?
What is the correct library to use for this usage?

How to get detailed error message thrown by express in angular

I am sending an HTTP request from angular to a node/express API. How do I get the actual error message I send from the node/express API
I am handling my exceptions well when they are thrown in the API but the moment I try to read the message in Angular I only get the name of the type of error I throw. For example, if I throw a 409 the error received by angular is just "Conflict" and does not contain the details I send. Please look at my code below.
I am sending my request as below
register(user: UserAccount) {
return this.http
.post(`${config.apiUrl}/users/register`, user)
.pipe(
map((res: HttpResponse<Response>) => {
return res;
}))
.pipe(catchError(err => this.errorHandler.handleError(err)));
}
My handle error is as below:
handleError(error: HttpErrorResponse) {
console.log(error);
if (error) {
let errMessage = '';
try {
errMessage = error.message;
} catch (error) {
errMessage = error.statusText;
}
return throwError(errMessage || error || 'Server error');
}
return throwError(error.error || error || 'Server error');
}
This how I am throwing my error when I occurs in my Node/Express API
registerUser (req, res) {
debug(chalk.blue(`*** insert user`))
userRepo
.create(req.body)
.then(user => {
debug(chalk.green(`*** Insert User ok!`))
res.status(200).json({
status: true,
error: null,
user: user
})
})
.catch(err => {
debug(chalk.red(`*** insertUser error: ${util.inspect(err)}`))
if (err['type'] && err['type'] === '409') {
res.status(409).json({
status: false,
error: err['message'],
user: null
})
} else {
res.status(400).json({
status: false,
error: err,
user: null
})
}
})
}
I want to be able to receive the json object with the information about the error but all I am getting when I access the error item is, for example, in the case of raising a 409, I only get 'Conflict'
The response data in case of error is inside the error property of HttpErrorResponse. So you may need to modify the handleError method as below.
handleError(error: HttpErrorResponse) {
console.log(error);
if (error) {
let errMessage = '';
try {
// error.error holds the json response sent from API.
errMessage = JSON.stringify(error.error);
} catch (error) {
errMessage = error.statusText;
}
return throwError(errMessage || error || 'Server error');
}
return throwError(error.error || error || 'Server error');
}
Server-side express code
registerUser(req, res) {
debug(chalk.blue(`*** insert user`))
userRepo
.create(req.body)
.then(user => {
/**
* SUCCESS TO-DO
* .
* .
* .
* .
*/
return res.send(200).json(user)
})
.catch(err => {
/**
* error handler in server
* FAILURE TO-DO
* .
* .
* .
*/
if (err['type'] && err['type'] === '409') {
res.status(409).json({
status: false,
error: 'some 409 type error',
user: null
})
} else {
res.status(400).json({
status: false,
error: 'some 400 type error',
user: null
})
}
})
}
Your angular code
handleError(error: HttpErrorResponse) {
console.log(error);
if (error) {
let errMessage = '';
try {
errMessage = error.message; // <- here is the problem
} catch (error) {
errMessage = error.statusText;
}
return throwError(errMessage || error || 'Server error');
}
return throwError(error.error || error || 'Server error');
}
Firstly, if I may rename your HttpErrorResponse object as http_error as it is too generic. However, the trick lies in reading from the error key of the http_error object, and not from the message key.
Client-side error handler(angular)
handleError(http_error: HttpErrorResponse) {
// {status: false, error: 'some 409/400 type error', user: null }
const errMessage = http_error.error;
/* TO-DO STUFF */
return throwError(errMessage || 'Server error');
}

Resources