5 min read

Error Handling in JS

Error object in JS

  • Error objects are thrown automatically when runtime errors occur.
  • Automatic runtime errors that occur due to system failures or incorrect code execution
  • The following code gives an error automatically:
let person = null;
console.log(person.name); // This will throw an error: Cannot read property 'name' of null
console.log("This line will not execute because of the crash");
VM33:2 Uncaught TypeError: Cannot read properties of null (reading 'name')
    at <anonymous>:2:20
  • The Error object can also be used as a base object for user-defined exceptions.
  • It is useful when you want to signal errors due to logical issues rather than syntax or runtime failures.
  • The following code gives an user defined error.
let person = null;
if(person===null){
    throw new Error("Name can't be null")
}
console.log(person);
console.log("This line will not execute because of the crash");
VM180:3 Uncaught Error: Name can't be null at <anonymous>:3:11

Error Types in JS

  • EvalError: Creates an instance representing an error that occurs regarding the global function eval()
  • RangeError: Creates an instance representing an error that occurs when a numeric variable or parameter is outside its valid range.
  • ReferenceErrror: Creates an instance representing an error that occurs when de-referencing an invalid reference.
  • SyntaxError: Creates an instance representing a syntax error.
  • TypeError: Creates an instance representing an error that occurs when a variable or parameter is not of a valid type.
  • URIError: Creates an instance representing an error that occurs when encodeURI() or decodeURI() are passed invalid parameters.
  • AggregateError: Creates an instance representing several errors wrapped in a single error when multiple errors need to be reported by an operation, for example by Promise.any().
  • InternalError: Creates an instance representing an error that occurs when an internal error in the JavaScript engine is thrown. E.g. “too much recursion”.

Error Instance Properties

  • message: Error message for user-created Error objects, this is the string provided as the constructor’s first argument.
  • name: Represents the name for the type of error. For Error.prototype.name, the initial value is "Error". Subclasses like TypeError and SyntaxError provide their own name properties.
  • stack: These properties are own properties of each Error instance.

Error Handling In JavaScript

Error handling in JS is done using try()…catch()…finally()`

  • We can throw exceptions using throw statement and handle them using the try...catch statements.
  • The try...catch statement consists of a try block, which contains one or more statements, and a catch block, containing statements that specify what to do if an exception is thrown in the try block.
  • We want the try block to succeed—but if it does not, we want control to pass to the catch block. If any statement within the try block (or in a function called from within the try block) throws an exception, control immediately shifts to the catch block. If no exception is thrown in the try block, the catch block is skipped.
  • The finally block executes after the try and catch blocks execute but before the statements following the try...catch statement.
  • The finally block will execute whether or not an exception is thrown.
  • Syntax
try{
}catch(error){

}finally{

}
  • The catch block specifies an identifier (exception in the preceding syntax) that holds the value specified by the throw statement. You can use this identifier to get information about the exception that was thrown.
  • Note: When logging errors to the console inside a catch block, using console.error() rather than console.log() is advised for debugging. It formats the message as an error, and adds it to the list of error messages generated by the page.

Program that crashes (without error handling)

  • This JavaScript code will crash when trying to access a property of undefined.
let person = null;
console.log(person.name); // This will throw an error: Cannot read property 'name' of null
console.log("This line will not execute because of the crash");

Program that doesn’t crash (with error handling)

  • Here’s the same program, but with error handling using a try...catch block.
let person = null;

try {
  console.log(person.name); // This will throw an error, but it will be caught
} catch (error) {
  console.log("An error occurred: " + error.message); // Error is handled here
}

console.log("This line will execute because the error was handled");
  • Using Error Instance Properties
let person = null;

try {
  console.log(person.name); // This will throw an error, but it will be caught
} catch (error) {
  console.error("An error occurred: " + error.name); // Error is handled here
    console.error("An error occurred: " + error.message)
    console.error("An error occurred: " + error.stack)
    console.error("An error occurred: " + error)
}

console.log("This line will execute because the error was handled");
- An error occurred: TypeError (anonymous) @ VM364:6
- VM364:7 An error occurred: Cannot read properties of null (reading 'name')
(anonymous) @ VM364:7
- VM364:8 An error occurred: TypeError: Cannot read properties of null (reading 'name') at <anonymous>:4:22 (anonymous) @ VM364:8
- VM364:9 An error occurred: TypeError: Cannot read properties of null (reading 'name') (anonymous) @ VM364:9

Practical Example - ATM Withdrawal (Without Error Handling)

function withdrawMoney(balance, amount) {
  if (amount > balance) {
    throw new Error("Insufficient funds");
  }

  balance -= amount;
  console.log(`Withdrawal successful! Remaining balance: $${balance}`);
}

let accountBalance = 100;

console.log("Attempting to withdraw $150...");
withdrawMoney(accountBalance, 150); // This will throw an error and crash
console.log("This line will not execute");

Practical Example - ATM Withdrawal (With Error Handling)

function withdrawMoney(balance, amount) {
  try {
    if (amount > balance) {
      throw new Error("Insufficient funds");
    }
    balance -= amount;
    console.log(`Withdrawal successful! Remaining balance: $${balance}`);
  } catch (error) {
    console.log(`Transaction failed: ${error.message}`);
  }
}

let accountBalance = 100;

console.log("Attempting to withdraw $150...");
withdrawMoney(accountBalance, 150); // This will be caught and handled

console.log("Program continues without crashing");