try-catch …. Always the confusion — JavaScript?

Amir Mustafa
5 min readMar 11, 2021

No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response, and for a thousand other reasons.But there’s a syntax construct try..catch that allows us to “catch” errors so the script can, instead of dying, do something more reasonable.

eg1

lalala;     
// Error msg:ReferenceError: lalala is not defined - code dies here
// my next codes.
console.log('initiating a service'); // this code will break

with try-catch

try {lalala;} catch(err) {console.log(err.stack);   // this will throw in console}console.log('next codes'); // this code will execute

TRICK:

  1. use try-catch wherever you feel javaScript engine will throw error.
  2. it will prevent code break

It works like this:

  1. First, the code in try {...} is executed.
  2. If there were no errors, then catch(err) is ignored: the execution reaches the end of try and goes on, skipping catch.
  3. If an error occurs, then the try execution is stopped, and control flows to the beginning of catch(err). The err variable (we can use any name for it) will contain an error object with details about what happened.

A. Try-catch works only for run-time errors:

B. Try-catch works synchronously only:

C. Error Objects Tricks:

Error object mainy has three keys: name, message and stack:

Eg.

try {   
lalala; // error, variable is not defined!
} catch(err) {
alert(err.name); // ReferenceError
alert(err.message); // lalala is not defined
alert(err.stack); // ReferenceError: lalala is not defined at
// (...call stack) // Can also show an
// error as a whole // The error is
// converted to string as "name: message"
alert(err); // ReferenceError: lalala is not defined
}

D. Real life example:

Eg1: good request:

// Valid JSON
let task = '{"companyNameAr":"جريبي","eadLicenseNumber":"CF-359","externalEntityLicenseNumber":"IN-2003833","companyName":"IN-2003833 TEST","licenseIssuanceEntityId":1,"profileCompanyNameAr":"","eqsApplicationId":5399,"profileCompanyId":null,"profileCompanyName":""}';
let user = JSON.parse(task);console.log(user);

Eg2: Some issues with JSON:

try {    let task = '{bad request}';    let user = JSON.parse(task);} catch(err) {    console.log('Error Object: ', err); // error prints as invalid json}// next codes will work

Eg3: We can purposely throw error

let json = '{ "age": 30 }'; // incomplete datatry { let user = JSON.parse(json); if(!user.name) {    throw new SyntaxError('Error: incomplete user data');    alert(user.name); }} catch(e) {console.log(e.message); // O/P - Error: incomplete user data}

E. Throw the error if catch is unaware of the error:

Catch should only process errors that it knows and “rethrow” all others.

The “rethrowing” technique can be explained in more detail as:

  1. Catch gets all errors.
  2. In the catch(err) {...} block we analyze the error object err.
  3. If we don’t know how to handle it, we do throw err.

Usually, we can check the error type using the instanceof operator:

Eg.

function readData() {    let json = '{ "age": 30 }';    try {        // ...        blabla(); // error!    } catch (e) {     // ...     if (!(e instanceof SyntaxError)) {         throw e; // rethrow (don't know how to deal with it)     }   }}try {    readData();} catch (e) {    alert( "External catch got: " + e ); // caught it!}

F. Try-catch and finally:

The try..catch construct may have one more code clause: finally.

If it exists, it runs in all cases:

  • after try, if there were no errors,
  • after catch, if there were errors.

Eg.

try {
... try to execute the code ...
} catch(e) {
... handle errors ...
} finally {
... execute always ...
}

Finally is generally used when it expects some data.

F. Global Catch

The information from this section is not a part of the core JavaScript — Enviromment specific

Let’s imagine we’ve got a fatal error outside of try..catch, and the script died. Like a programming error or some other terrible thing.

Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don’t see error messages), etc.

There is none in the specification, but environments usually provide it, because it’s really useful. For instance, Node.js has process.on("uncaughtException") for that. And in the browser we can assign a function to the special window.onerror property, that will run in case of an uncaught error.

Eg.

<script>   // Handeling global error
window.onerror = function(message, url, line, col, error) {
alert(`${message}\n At ${line}:${col} of ${url}`);
};
function readData() {
badFunc(); // Whoops, something went wrong!
}
readData(); </script>

Summary:

The try..catch construct allows to handle runtime errors. It literally allows to “try” running the code and “catch” errors that may occur in it.

The syntax is:

try {
// run this code
} catch(err) {
// if an error happened, then jump here
// err is the error object
} finally {
// do in any case after try/catch
}

There may be no catch section or no finally, so shorter constructs try..catch and try..finally are also valid.

Error objects have following properties:

  • message – the human-readable error message.
  • name – the string with error name (error constructor name).
  • stack (non-standard, but well-supported) – the stack at the moment of error creation.

If an error object is not needed, we can omit it by using catch { instead of catch(err) {.

We can also generate our own errors using the throw operator. Technically, the argument of throw can be anything, but usually it’s an error object inheriting from the built-in Error class. More on extending errors in the next chapter.

Rethrowing is a very important pattern of error handling: a catch block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn’t know.

Even if we don’t have try..catch, most environments allow us to setup a “global” error handler to catch errors that “fall out”. In-browser, that’s window.onerror.

--

--

Amir Mustafa

JavaScript Specialist | Consultant | YouTuber 🎬. | AWS ☁️ | Docker 🐳 | Digital Nomad | Human. Connect with me on https://www.linkedin.com/in/amirmustafa1/