Exception Handling

Exception handling in TypeScript is similar to exception handling in Java that’s based on the try/catch syntax. It allows you to handle runtime errors in your code in a graceful manner by escaping the normal flow of the program in the presence of errors by giving control to a different section of the code that can do damage control.

Exception Handling Basics

In both TypeScript and Java, you can use try-catch blocks to handle exceptions. To recall, a try-catch block:

  • consists of a try block, which contains the code that could throw an exception
  • a catch block, which contains the code that handles the exception thrown from the try block
  • an optional finally block

Here’s how we write code in Java to handle exceptions:

try {
  // code that may throw an exception
} catch (Exception e) {
  // code to handle the thrown exception
}

TypeScript syntax is very similar. This is how we’d write the try-catch in TypeScript:

try {
  // code that may throw an exception
} catch (error) {
  // code to handle the thrown exception
}

The exception itself is an object, which is passed to the catch block as an argument (in this case error). In Java, all exceptions must be a subtype of the Throwable class, which sit at the root of the exception hierarchy in Java. In TypeScript, the thrown exception can be any type, including primitives, objects, and even functions.

// Throwing a string
function divideThrowString(x: number, y: number): number {
   if (y === 0) {
      throw "Cannot divide by zero"; // throw a string
   }
   return x / y;
}

try {
   console.log(divideThrowString(10, 0));
} catch (e) {
   console.error(e); // Outputs "Cannot divide by zero"
}


// Throwing an object
function divideThrowObject(x: number, y: number): number {
   if (y === 0) {
      throw { message: "Cannot divide by zero" };
   }
   return x / y;
}

try {
   console.log(divideThrowObject(10, 0));
} catch (e) {
   console.error(e.message); // Outputs "Cannot divide by zero"
}

// Throwing a function
function divideThrowFunction(x: number, y: number): number {
   if (y === 0) {
      throw function() { console.log("There has been an error") };
   }
   return x / y;
}

try {
   console.log(divideThrowFunction(10, 0));
} catch (e) {
   e(); // Outputs "There has been an error"
}

At this point you may wonder what’s the type of the variable in catch e.g error or e. If you don’t specify a type, the type of the variable in the catch block is inferred from the type of the thrown exception.

try {
   throw new Error("I'm an error Object");
} catch (error) {
   console.log(typeof error); // Outputs "object"
}

try {
   throw "I'm a String";
} catch (error) {
   console.log(typeof error); // Outputs "string"
}

Recall that TypeScript compiles its code to JavaScript. For this reason, there’s no way for TypeScript compiler to know at runtime what type of exception will be passed to the catch block. For this reason, the type of error variable in the catch block must be of type any or undefined. E.g.

try {
   throw new Error("Something went wrong");
} catch (error: any) {
   console.log(error.message); // Outputs "Something went wrong"
}

To handle multiple types of exceptions, you can use union types e.g. Error | any as shown in the example below:

try {
   throw new Error("Something went wrong");
} catch (error: Error | any) {
   if (error instanceof Error) {
      console.log(error.message); // Outputs "Something went wrong"
   } else {
      console.log(error);
   }
}

TypeScript doesn’t support support multiple catch blocks like Java. To handle different types of exceptions, you must use if... else if... else inside the single catch block.

Like Java, in TypeScript the finally block is optionally used in a try-catch statement to specify a block of code that’s always executed when the try block exits. The finally block is useful for cleaning up resources.

try {
   // Code that may throw an exception is here
} catch (error) {
   // Code to handle the exception goes here
} finally {
   // Code to be executed goes here when try exits.
}

Licenses and Attributions


Speak Your Mind

-->