EDIT
This edition is for question in comments.
If you want no waiting, you could just remove await keyword, but you will not get the any error message throw from car_reporter.report.
async function report_car(user_id, car) {
var options = { car: car };
try {
car_reporter.report(user_id, options);
} catch (error) {
logger.error(error);
}
}
You could try this example.
You will get the UnhandledPromiseRejectionWarning error.
And your catch block will not be executed.
function test () {
return new Promise((res, rej) => setTimeout(() => {
rej("not good")
}, 2000))
}
async function main() {
try {
test()
} catch (error) {
console.log("Get error");
console.log(error);
}
}
main()
In this case, you could add .catch behind test().
function test () {
return new Promise((res, rej) => setTimeout(() => {
rej("not good")
}, 2000))
}
async function main() {
try {
test().catch((error) => {
console.log("Get error inside");
console.log(error)
})
} catch (error) {
console.log("Get error");
console.log(error);
}
console.log("done");
}
main()
After you execute above code, you will find done is printed first. Then Get error inside is printed second. We assume you will display some message after console.log("done"), but you don't know test() if execute successfully or not. So basically, you could not display message without waiting in the first executing.
Unless, you could show message like "processing" to your user first. Then, tell your user this test() is successful or not.
Back to your code. When you remove the await, your catch block will not work well. So, you need to add .catch behind your car_reporter.report.
Then do something with error message in inside catch block. You could send a email tell your user this report broken. But, I'm not sure where this program run. If it run with express as api service, polling is also a method.
async function report_car(user_id, car) {
var options = {car: car};
try {
car_reporter.report(user_id, options).then((result) => {
// send email with this successful result
// tell your user this report is fine.
}).catch((error) => {
// send email with this error message
// tell your user this report is broken.
});
} catch (error) {
logger.error(error);
}
// told your user report is still processing.
}
Original Answer
I modify code based on yours.
Because you're using the axios here, I'll use async-await to refactor the code.
I'll first use async-await to refactor usage in report_car function.
async function report_car(user_id, car) {
var options = { car: car };
var result = await car_reporter.report(user_id, options);
if (result instanceof Error) {
logger.error(result);
}
}
Then I need to add try-catch to avoding the UnhandledPromiseRejectionWarning.
Any throw error from car_reporter.report will be in the catch block.
async function report_car(user_id, car) {
var options = { car: car };
try {
var result = await car_reporter.report(user_id, options);
} catch (error) {
logger.error(error);
}
}
Next, if username is null, there is an error message.
Change it to throw instead of return because of using async-await outside.
If you use return, it will be treated as a resolved promise.
So, use throw and make this error happen on the catch block outside.
report: function (username, options) {
if (username === null) {
throw new Error('Invalid username');
}
if (fs.existsSync(this.script_path)) {
return this.scriptReport(username, options);
} else {
return this.APIReport(username, options);
}
},
And you should use throw instead of return when you're handling the error.
Then you'll get the error in catch block of report_car function.
APIReport: function (username, options) {
if (!(this.httpClient)) {
this.init();
}
try {
if ('car' in options) {
var reqConfig = {
method: 'post',
url: '/car',
headers: {
'content-type': 'application/json',
},
data: {
'carName': carName, // global
'username': username,
'car': options.car
}
};
const result = await this.httpClient(reqConfig)
// handle something with result if you need it
// other code here ...
}
} catch (e) {
// you could custom error message here, and throw to outside
// like `throw new Error("axios error")`
console.log(e)
throw new Error("axios error")
}
},
But, what happen when there is error in other code here at above example.
Maybe you call a non-exist function, it will throw undefined error.
Your catch block also catch it.
In this moment, you will throw new Error("axios error") because you customize your error message.
So, problem is here.
How do I tell the different between these error or customize?
You could directly add catch in your axios, then customize the error message like following code.
APIReport: function (username, options) {
if (!(this.httpClient)) {
this.init();
}
try {
if ('car' in options) {
var reqConfig = {
method: 'post',
url: '/car',
headers: {
'content-type': 'application/json',
},
data: {
'carName': carName, // global
'username': username,
'car': options.car
}
};
const result = await this.httpClient(reqConfig).catch((error) => {
throw new Error("APIReport axios error")
})
// handle something with result if you need it
// other code here ...
}
} catch (e) {
// here, you could throw other customized error message
// like, throw new Error("APIReport exception")
console.log(e)
throw e;
}
},
But, if you throw error in axios catch block, node will not execute following code which I mention in other code here.
If you want the code continue executing when axios has error, you should use return instead of throw in axios catch block.
If you want the code not continue executing when axios has error, you should use throw.
It depend on situation you want.
The whole code look like this.
const car_reporter = {
httpClient: null,
scriptReport: function (username, options) {},
APIReport: function (username, options) {
if (!(this.httpClient)) {
this.init();
}
try {
if ('car' in options) {
var reqConfig = {
method: 'post',
url: '/car',
headers: {
'content-type': 'application/json',
},
data: {
'carName': carName, // global
'username': username,
'car': options.car
}
};
const result = await this.httpClient(reqConfig).catch((error) => {
throw new Error("APIReport axios error")
})
// handle something with result if you need it
// other code here ...
}
} catch (e) {
// here, you could throw other customized error message
// like, throw new Error("APIReport exception")
console.log(e)
throw e;
}
},
report: function (username, options) {
if (username === null) {
throw new Error('Invalid username');
}
if (fs.existsSync(this.script_path)) {
return this.scriptReport(username, options);
} else {
return this.APIReport(username, options);
}
},
init: function () {
this.httpClient = axios.create({
baseURL: this.api_url
});
}
};
module.exports = car_reporter;
async function report_car(user_id, car) {
var options = { car: car };
try {
var result = await car_reporter.report(user_id, options);
} catch (error) {
logger.error(error);
}
}
I hope this could help you.