Don’t abuse language features

Recently we had a situation in a ES6 project. We were using some of new features ES6 in a wrong way. I’m writing this blog post to explain what was the issue and what is the solution to avoid these kind of problems it the future.

ES6 Promise

We designed a Message box class which accepts a title, text and buttons. Then, you can call open to display the message box. User can decide to click on Yes or No button (assume there is a Accept / Reject button on the message box).

That open function returns a Promise which fulfills the Promise if user clicked on Yes and rejects it if you click on No button. Therefore you can decide what to do with the Promise.

This is sample of that API:


let msg = Message({ 
	text: "Hello world", 
	title: "Are you sure?",
}).open(); //msg is a Promise now 

 

Now, to test and see if user clicked on Accept or Reject button, you can use then() or catch() of Promise object. But we didn’t use these functions. Instead, we use try...catch with async / await keywords.

Incorrect usage of Promise

Another way to handle Promise is to use async and await keywords, like so:

 


(async function () {
	try {
  	let res = await ReturnPromise();
    console.log("gotcha", res);
  } catch (e) {
	console.warn('opssss');
  }
}());

 

It would reach the catch block if user clicked on Reject and the try block if Accept (actually, it would execute anything after await keyword, otherwise, it throws an exception and hits the catch block).

Well, above usage is correct, too, but there are many problem with that approach:

1) Suppressing errors

If you add anything to that try block, you would need to handle the errors on the catch block. If you don’t handle them in try catch block, it would suppress the errors and wouldn’t be able to understand what is going on in your application in case of any errors.

2) Catch block

You cannot remove the catch block. You should either leave it empty or add something between the catch block. Imagine your application with a milion of empty catch blocks:


(async function () {
	try {
  	let res = await ReturnPromise();
    console.log("gotcha", res);
  } catch (e) { } // <-- this is the empty block
}());

 

Also, sometimes you just need to handle the Accept case and there is no need to handle the catch or Reject case. Now, you can’t do anything but adding an empty catch block.

3) You are not handling an error!

You should use try catch when you want to handle an error and do something instead of letting the application to crash and exit the main. Is that case, we were not handling an error. Clicking on a Reject button is not an error.

 

Write maintainable code

Remember, you are writing codes and it should be readable and understandable for other contributors and if you use some sort of weird syntax in your program, it doesn’t prove anything about the level of your coding skills or how talented you are. A good code is boring to read.