Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Errors and try...catch

A program cannot always do what it is asked to: data arrives in the wrong format, a server does not respond, a required value is missing. When an error occurs, execution stops, and nothing written after that point runs. The try...catch construct lets you catch the error and carry on.

try and catch

Code that may fail goes into a try block. If an error happens, execution jumps straight to the catch block:

try {
  JSON.parse('this is not JSON');
} catch (error) {
  console.log('Could not parse the data'); // Could not parse the data
}

JSON.parse() could not read the string and threw an error. Without try...catch the program would have stopped there. If there is no error, the catch block is simply skipped.

The error object

The parentheses after catch name a variable — it receives an object describing the error. Its name property holds the kind of error, and message the text:

try {
  undefinedFunction();
} catch (error) {
  console.log(error.name);    // ReferenceError
  console.log(error.message); // undefinedFunction is not defined
}

Built-in error types

The error name tells you what went wrong. These are the most common ones:

TypeWhen it happens
ReferenceErrorusing a variable that was never declared
TypeErroran action does not suit the value: calling a non-function, a property of undefined
SyntaxErrorcode or JSON is written incorrectly
RangeErrora number outside the allowed range
try {
  const user = undefined;
  user.name;
} catch (error) {
  console.log(error.name); // TypeError
}

throw

The throw statement raises an error yourself. This is how a function reports that it cannot do its job. An error is created with new Error('text'):

function divide(a, b) {
  if (b === 0) {
    throw new Error('Cannot divide by zero');
  }
  return a / b;
}
 
try {
  console.log(divide(10, 2)); // 5
  console.log(divide(1, 0));
} catch (error) {
  console.log(error.message); // Cannot divide by zero
}

The first call worked, the second threw an error, and control went to catch — the second console.log never ran.

finally

The finally block always runs — both after a successful try and after catch. It is where you finish what you started: hide a loading indicator, close a file or a connection:

try {
  console.log('Loading data');
  throw new Error('Network failure');
} catch (error) {
  console.log(error.message);
} finally {
  console.log('Loading finished');
}
// Loading data
// Network failure
// Loading finished

Common mistake

An empty catch block "swallows" the error: the program goes on with bad data, and finding the cause later is very hard.

try {
  JSON.parse('{ broken }');
} catch (error) {
  // empty: nobody will ever know about the error
}

Catch only the errors you know how to handle. If you cannot handle one, at least report it with console.error(error).

Thanks for reading!

Donate to the site — we work hard for you.