Javascript syntax errors swallowed and hidden in async/await functions - javascript

I'm learning Electron.js and I want to use async/await feature in my code but I'm a bit disappointed because syntax errors are swallowed and silent which make my future projects a nightmare for debugging.
db module:
exports.connect = function(){
return new Promise( (resolve, reject) => {
connection = mysql.createConnection({
host : host,
port : port,
user : user,
password : null, // or the original password : 'apaswword'
database : database
});
query = util.promisify(connection.query).bind(connection);
connection.connect(function(error) {
// in case of error
if(error){
reject(error);
}
resolve(true);
});
connection.on('error', error => {
dispatcher.send('connection-error', error.code);
});
});
}
bootstrap module:
async function connectDB(){
try{
let connected = await db.connect(THIS_SHOULD_THROW_ERROR);
return connected;
}catch( error ){
dispatcher.send('connection-error', error);
}
}
exports.init = async function( win ){
dispatcher.init(win);
try{
const connected = await connectDB();
/*if(!connected){
dispatcher.send('fatal-error', "MYSQL NOT CONNECTED");
}*/
}catch( error ){
dispatcher.send('fatal-error', error);
}
}
This code is trying to connect to mysql and send error if it can't connect, but notice the syntax error "THIS_SHOULD_THROW_ERROR" that should halt execution or throw error, but it doesn't and my code has no errors at all even if it can't connect to mysql.
Notice that if I remove syntax error my code works well and catches mysql connection error.
I've read everywhere that is normal behavior of javascript async/promises code, but I'd like to know if there is a solution to catch syntax errors to make my debuging easier. Thank you

If you have a syntax error inside a try/catch block or you are using a catch all mechanism (i.e. process.on('uncaughtException'...) the syntax error would be swallowed:
/* content of test.js */
console.log('hello')
THIS_SHOULD_THROW_ERROR // comment this line and run again
try {
THIS_SHOULD_THROW_ERROR_BUT_DOESNOT
} catch (err) {
// using err will throw exception: console.log(err)
console.log('error happened')
}
Now run the script with and without comment in the line specified:
$ node test.js
So you are doing such somewhere in your code.
PS:
async function connectDB(){
try{
let connected = await db.connect(THIS_SHOULD_THROW_ERROR);
return connected;
}catch( error ){
dispatcher.send('connection-error', error);
// throw error
}
}
The db.connect(THIS_SHOULD_THROW_ERROR) is in try block while you don't throw the error. If dispatcher.send doesn't throw the error in some point that error is swallowed.

Thanks to Xarqron & Bergi I made it finnaly work, I just had to throw error in both connectDB and init catch's
async function connectDB(){
try{
let connected = await db.connect(THIS_SHOULD_THROW_ERROR);
return connected;
}catch( error ){
dispatcher.send('connection-error', error);
throw error;
}
}
exports.init = async function( win ){
dispatcher.init(win);
try{
const connected = await connectDB();
/*if(!connected){
dispatcher.send('fatal-error', "MYSQL NOT CONNECTED");
}*/
}catch( error ){
dispatcher.send('fatal-error', error);
throw error;
}
}
Do you advice to always throw error in every catch block so that debugging would be easier ? Because I had hard time to find this kind of bug without any console warning or error

Related

How to handle errors in Firestore transactions inside https cloud function?

I want to throw an https error to the client if some pre-condition fails (in the read part of the transaction). Also, I want to throw an "unavailable" error if the transaction fails because of an unexpected error.
await firestore
.runTransaction(async (transaction) =>
transaction.get(userRef).then((doc) => {
const { totalPoints } = doc.data();
if (totalPoints > 1000) {
...
} else {
throw new functions.https.HttpsError(
"failed-precondition",
"You have less than 1000 points."
);
}
})
)
.catch((err) => {
throw new functions.https.HttpsError(
"unavailable",
"Please, try again later."
);
});
The problem is that, if I throw the https error inside the then, the catch will get it and throw an other https error.
How can I avoid entering the catch when throwing the "failed-precondition" error?
I have solved the problem with Promise.reject()
I know that this is not the best way, but works. Looking for a better approach.
await firestore
.runTransaction(async (transaction) =>
transaction.get(userRef).then((doc) => {
const { totalPoints } = doc.data();
if (totalPoints > 1000) {
...
} else {
return Promise.reject({
type: "failed-precondition",
message: "You have less than 1000 points."
});
}
})
)
.catch((err) => {
if (err.type === "failed-precondition") {
throw new functions.https.HttpsError(err.type, err.message);
}
else {
throw new functions.https.HttpsError(
"unavailable",
"Please, try again later."
);
}
});
For all of my Cloud Functions, I have a top-level try-catch that catches unknown errors and lets HttpsError errors continue down the chain as they are.
if (e instanceof https.HttpsError) throw e;
console.error("Encountered with an undefined error. Error: ", e);
throw new https.HttpsError(
"unknown",
"There was an unknown error."
);
You can do a similar thing (replacing https.HttpsError with functions.https.HttpsError of course).
This allows me to pass on the errors I have pre-defined inside the code as they are, and also provide my users an error message while logging the error for Cloud Logging.

How to get error line using Nestjs avoiding duplicate code

I made a controller on nestjs as below.
#Post()
public async addConfig(#Res() res, #Body() createConfigDto: CreateConfigDto) {
let config = null;
try {
config = await this.configService.create(createConfigDto);
} catch (err) {
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
status: 500,
message: 'Error: Config not created!',
});
}
if (!config) {
return res.status(HttpStatus.NOT_FOUND).json({
status: 404,
message: 'Not Found',
});
}
return res.status(HttpStatus.OK).json({
message: 'Config has been created successfully',
config,
});
}
And there is a service in other file.
public async create(createConfigDto: CreateConfigDto): Promise<IConfig> {
do something 1
do something 2
do something 3
return result;
}
If an internal server error occurs among "do somehting 1,2 or 3" when I request to this api, it will gives me response 500.
But I want to know in which line the error happend.
Therefore I made catch line function.
const getStackTrace = () => {
const obj = {};
Error.captureStackTrace(obj, getStackTrace);
return obj.stack;
};
And I wrap the code with this function, like this
public async create(createConfigDto: CreateConfigDto): Promise<IConfig> {
try{
do something 1
}catch(error){
console.log(error)
getTrace()
}
try{
do something 2
}catch(error){
console.log(error)
getTrace()
}
try{
do something 3
}catch(error){
console.log(error)
getTrace()
}
return result;
}
But the problem is the service code will grow a lot with this trace function.
I want to know whether there is more efficient way avoiding duplicate code using nestJs for this case.
I think interceptor or execption filter help this.
But I don't know how to code for this case , since I 'm about to start using nestjs.
Thank you for reading my question.

Unable to handle mysql error using async await

I am new to node js. I learned am learning to execute MySQL queries using async/await instead of callback functionality.
I am able to get data on success but If any error occurs, I couldn't catch that error. Please suggest me how to achieve so.
My MySQL code to create a row in the education table
Education.create = async (newEducation) => {
try {
const res = await sql.query("INSERT INTO education SET ?", newEducation);
return await {id: res.insertId, ...newEducation};
}catch(err) {
// I couldn't catch DUPLICATE ENTRY ERROR or any other MYSQL generated error
console.log(": ---------------------------")
console.log("Education.create -> err", err)
console.log(": ---------------------------")
return err;
}
}

SQLITE_MISUSE: bad parameter or other API misuse [duplicate]

I've searched on how to create a sqlite3 database with a callback in Node.js and have not been able to find any links. Can someone point me towards documentation or provide a 2-3 line code sample to achieve the following:
Create a sqlite3 database and catch an error if the creation fails for any reason.
Here is what I've tried:
let dbCreate = new sqlite3.Database("./user1.db", sqlite3.OPEN_CREATE, function(err){
if(!err){
logger.infoLog("Successfully created DB file: " + dbFileForUser + " for user: " + username );
} else {
logger.infoLog("Failed to create DB file: " + dbFileForUser + ". Error: " + err );
}
});
dbHandler[username] = dbCreate;
When I execute this, I get the following error:
"Failed to create DB file: ./database/user1.db. Error: Error: SQLITE_MISUSE: bad parameter or other API misuse"
This call without callback works just fine.
var customDB = new sqlite3.Database("./custom.db", sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
But in this, I will not know if I run into any errors while creating the Database.
Try this:
let userDB = new sqlite3.Database("./user1.db",
sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
(err) => {
// do your thing
});
Example.
#Irvin is correct, we can have a look at http://www.sqlitetutorial.net/sqlite-nodejs/connect/ and
check it says if you skip the 2nd parameter, it takes default value as sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE
and in this case if database does not exist new database will be created with connection.
sqlite3.OPEN_READWRITE: It is to open database connection and perform read and write operation.
sqlite3.OPEN_CREATE : It is to create database (if it does not exist) and open connection.
So here is the first way where you have to skip the 2nd parameter and close the problem without an extra effort.
const sqlite3 = require("sqlite3").verbose();
let db = new sqlite3.Database('./user1.db', (err) => {
if (err) {
console.error(err.message);
} else {
console.log('Connected to the chinook database.|');
}
});
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection.');
});
And this is the 2nd way to connect with database (already answered by #Irvin).
const sqlite3 = require("sqlite3").verbose();
let db = new sqlite3.Database('./user1.db', sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE
, (err) => {
if (err) {
console.error(err.message);
} else {
console.log('Connected to the chinook database.');
}
});
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection.');
});

How to check function error using if/else statement?

I am creating session and sending traps to snmp devices, my code is working as expected and sending trap messages to host, Now below i have added validation to check if session has error while establishing connection, then throw error dont send trap message. So my question here is how can we execute function while checking if/esle condition and see if error exist in validateSession if error exist close session else send trap.
main.js
var session = snmp.createSession(host,"public",sessionOptions);
try {
function validateSession(){
session.on ("error", function (error) {
console.log (error);
session.close ();
});
};
if(!validateSession(){
session.trap(trapOid, varbinds, options, function (error) {
if (error)
console.log(error);
else
console.log('SNMP successfully delivered');
});
})
} catch (e) {
console.log("SNMP processing error: " + e);
}

Categories

Resources