Use try/catch on method - javascript

I use multiple same try/catch test on many object method. So, i would like create try/catch method for refacto my code, but the error is not returned.
For exemple :
#autobind
async forgottenPassword(req, res) {
return this.callService(
res,
async () => await companyService.forgottenPassword(req.body.formData)
);
}
callService(res, func) {
try {
func();
} catch (error) {
res.statusMessage = error.message;
res.status(error.statusCode);
} finally {
res.end();
}
}
My catch is never called :/
Anyone know did I make a mistake ?
Thank you !

You need to make your callService async and use await there too.
#autobind
async forgottenPassword(req, res) {
return this.callService(
res,
async () => await companyService.forgottenPassword(req.body.formData)
);
}
async callService(res, func) {
try {
await func();
} catch (error) {
res.statusMessage = error.message;
res.status(error.statusCode);
} finally {
res.end();
}
}

Related

Redis get function

I'm getting github repo data, and then i store it in redis with set. with get am getting current data, but when i trying add function to get it's not working.
let redisClient;
(async () => {
redisClient = redis.createClient();
redisClient.on("error", (error) => console.error(`Error : ${error}`));
redisClient.on("connect", function () {
console.log("Redis Connected!");
});
await redisClient.connect();
})();
// Make request to Github for data
async function getRepos(req, res, next) {
try {
console.log("Fetching Data...");
const { username } = req.params;
// with this am getting result
const cacheResults = await redisClient.get(username);
console.log(cacheResults);
// with this am not getting result, how can i fix this?
redisClient.get(username, (err, data) => {
console.log(data);
});
const response = await fetch(`https://api.github.com/users/${username}`);
const data = await response.json();
const repos = data.public_repos;
// Set data to Redis
redisClient.set(username, JSON.stringify(repos));
res.send(setResponse(username, repos));
} catch (e) {
console.log(e);
res.status(500);
}
}
it's don't console.log(data), i searched a lot and everyone have one example how to use get function, but in me case it's don't log, whats am doing wrong?
this is my cache function
// Cache middleware
async function cache(req, res, next) {
const { username } = req.params;
try {
await redisClient.get(username).then((data) => {
if (data !== null) {
res.send(setResponse(username, data));
} else {
next();
}
});
} catch (error) {
console.log(error.toString());
}
}
app.get("/repos/:username", cache, getRepos);
it's works, but time finish times with cache and without it are same? am doing something wrong?
can you try like this
redisClient.get(username).then((data) => {
console.log(data);
});

async.waterfall top level exception handler not working properly with async

im trying to make a top level exception handler to catches error from async.waterfall however everything works fine until async is used, please help me.
async function wrap(_: Function, fn: Function) {
let result: any = null;
try {
result = await fn(); // crashes when await is used
} catch (err) {
_(err);
}
_(null, result);
}
export default function (req: express.Request, res: express.Response, next: Function) {
try {
waterfall([
(next: Function) => {
wrap(next, async () => {
await delay(10000);
return true;
});
},
(a: boolean, next: Function) => {
wrap(next, () => {
if (a)
throw new Error('Error', 500); // should get catched by main try catch
});
}
], (err: any) => {
if (err)
throw err;
});
} catch (err: any) {
console.log(err);
next(err);
}
}
The main try catch was causing the request to stop the whole server. Removing it and using "next" instead solved my problem.

How to handle errors with Async and Await [Node.js]

I have already a function written with bluebird promises and I would like to rewrite it with async and await. When I have made the changes I have found out that earlier with promises the reject statement always transfers the control to called function catch block though if the catch block is already there in the file from where we are rejecting. How to handle this situation properly with async and await?. (Added comments to the code to explain the issue)
With Promise:
const callingFunc = (req, res) => {
return new Promise((resolve, reject) => {
// execute request which returns promise
functionCall()
.then((response) => {
let error;
try {
xml2js(response.body, { explicitArray: false }, (err, result) => {
if (err) {
return reject(err); /* throws the correct error to catch block of the file from where callingFunc is called*/
}
if (!_.isEmpty(result.Response.errorCode)) {
return reject(result.Response); /* throws the correct error to the catch block of the file from where callingFunc is called*/
}
return resolve(result);
});
} catch (e) {
error = new Error('xml2js conversion error');
reject(error);
}
})
.catch((error) => {
const Error = new Error('Internal Server Error');
reject(Error);
});
});
};
With async and await:
const callingFunc = (req, res) => {
try {
const response = await functionCall();
let error;
try {
xml2js(response.body, { explicitArray: false }, (err, result) => {
if (err) {
throw (err); /* throws the error to the below catch block and returning xml2js conversion error and changing behaviour*/
}
if (!_.isEmpty(result.Response.errorCode)) {
throw result.Response; /* throws the error to the below catch block and returning xml2js conversion error and changing behaviour*/
}
return result;
});
} catch (e) {
error = new Error('xml2js conversion error');
throw error;
}
} catch(error) {
const Error = new Error('Internal Server Error');
throw Error;
}
};
If functionCall returns a promise, then this code is inappropriate...
return new Promise((resolve, reject) => {
// execute request which returns promise
functionCall()
.then((response) => {
If xml2js is async using callbacks, then it is appropriate to wrap it in a promise...
// return a promise that resolves with the result of xml2js
async function xml2js_promise(body) {
return new Promise((resolve, reject) => {
xml2js(body, { explicitArray: false }, (err, result) => {
if (err) reject(err);
else if (!_.isEmpty(result.Response.errorCode)) reject(result.Response);
else resolve(result);
});
});
}
Now we can await these. There's no need to nest the try's. (And you only need the try if you're going to do something on the catch).
async callingFunction = (req, res) => {
try {
const response = await functionCall();
} catch (error) {
// do something with this error
}
try {
const result = await xml2js_promise(response.body)
} catch(error) {
// do something with this error
}
return result;
}

Async function with one try catch block

async function handlePersonalInformation(event) {
event.preventDefault();
const formData = initialInfo(data);
try {
await getPersonalInfo();
try {
await updatePersonalInfo(formData);
alert('Successfully updated!');
} catch (error) {
handleError(error);
}
} catch (error) {
try {
await createPersonalInfo(data);
alert('Your personal infromation has been saved');
} catch (error) {
handleError(error);
}
}
}
I am trying to refactor this function using only one try / catch block.
Unfortunately without success.
The problem with this code is that exception thrown by getPersonalInfo is treated as a normal business case: you always go with 'create...' fork if there's an error. Yet I don't think that's the correct implementation: what if that request failed because of some other reason, different from 404?
The better approach seems to be isolating this function, making it only throw real errors:
function wrappedGetPersonalInfo(data) {
try {
const res = await getPersonalInfo(data);
return res;
} catch (e) { // I wish there were typed catches
if (e instanceof NotFoundError) { // the check should suit your case
return null;
}
throw e;
}
}
... then you'll be able to streamline your code quite a lot:
try {
const res = await wrappedGetPersonalInfo(data);
if (res) {
await updatePersonalInfo(formData);
alert('Successfully updated!');
}
else {
await createPersonalInfo(data);
alert('Your personal infromation has been saved');
}
} catch (error) {
handleError(error);
}

mongoose Chaining with then and catch

How To Convert This Function to Chaining with then and catch?
Is better to Chained?
I mean User.findOne().then().catch()
User.findOne({_id: msg.chat.id}, (err, doc) => {
if (err) {
console.log(err);
}
if (doc) {
console.log(doc.name);
} else {
console.log('Empty');
}
});
The function you pass to then is called with the returned document (or null) if the operation succeeds, and the catch is called with the error if the operation fails (e.g. no connection). Putting it together looks like this:
User.findOne({_id: msg.chat.id})
.then(doc => {
if (doc) {
console.log(doc.name);
} else {
console.log('Empty');
}
}).catch(err => {
if (err) {
console.log(err);
}
});
As an aside, when you are searching for one document by id, then you can use findById:
User.findById(msg.chat.id)
.then(doc => {
if (doc) {
console.log(doc.name);
} else {
console.log('Empty');
}
}).catch(err => {
if (err) {
console.log(err);
}
});
Better switch to ES2017 async/await syntax, you can avoid Promise Hell
async function foo () {
try {
var doc = await User.findOne({_id: msg.chat.id}).exec()
if (doc)
return console.log(doc.name);
console.log('Empty');
} catch (err) { console.log(err) }
}
foo()
This will help you when you're going to nest DB calls or using for...loops.
async function foo () {
try {
var users = await User.find({}).exec()
for (var user in users) {
var tweets = await Tweet.find({_user: user._id}).exec()
user.tweets = tweets.map(t => t.text)
await user.save()
}
} catch (err) { console.log(err) }
}
foo()

Categories

Resources