Using try/catch in TypeScript: A Complete Guide

Updated: January 8, 2024 By: Guest Contributor Post a comment

Overview

TypeScript, a superset of JavaScript, has furnished coders with tools as versatile as a Swiss Army knife. It allows the structured handling of mishaps and errors via the otherwise quaint, yet profoundly robust ‘try/catch’ statements that add a safety net to your code. This guide intends to unfurl the mysteries of try/catch in TypeScript through illustrative examples.

Handling Basic Errors

At the heart of prudent programming lies the anticipation of error. Try/catch statements help manage such errors gracefully. Below is a simple TypeScript try/catch block:

try {
  // Code that might throw an error
  let result = JSON.parse(jsonString);
} catch (error) {
  console.error('JSON parsing error:', error);
}

Enhancing Error Handling

For more resilience, TypeScript employs type-checking within catch clauses. The ‘error’ parameter can be typed, aiding in differentiation among various exceptions:

try {
  // Code that might throw specific errors
} catch (error) {
  if (error instanceof SyntaxError) {
    // Handle syntax errors
  } else if (error instanceof RangeError) {
    // Handle range errors
  } else {
    // Handle all other errors
  }
}

Exception specificity strengthens the scope of error-handling. Note well the neat use of instanceof to navigate through the exceptions.

The Finer Bits: Advanced Error Handling

Advancing a notch, TypeScript allows tailored exceptions using custom error classes. Herein, an imitable demonstration:

class CustomError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'CustomError';
  }
}

try {
  // Code that might throw a CustomError
  throw new CustomError('Something went wrong!');
} catch (error) {
  if (error instanceof CustomError) {
    // Handle the custom error
  }
}

Observe with prudence: the upthrown error lands in the diligent, waiting palms of instanceof checking, thus concluding in exception-specific handling.

Asynchronous Error Catching

The perpetually spinning gears of TypeScript allow asynchronous error handling with async/await. Behold the pattern:

async function fetchData() {
  try {
    let response = await fetch('data.json');
    let data = await response.json();
  } catch (error) {
    console.error('Fetch error:', error);
  }
}

The promise-rejecting jitters are calmed by the catch’s embracing script, ensuring the asynchronous operation does not unceremoniously trip over its own feet.

Declaration Merging for Errors

TypeScript’s Declaration Merging can menustrate an error’s interface to provide additional properties:

interface CustomError extends Error {
  statusCode?: number;
}

function handleRequest(request: Request) {
  throw { message: 'Not found', statusCode: 404 } as CustomError;
}

try {
  handleRequest(new Request());
} catch (error) {
  let typedError = error as CustomError;
  if (typedError.statusCode) {
    // Process error
  }
}

Utilizing Finally Blocks

Attached to the tails of the try/catch is the ‘finally’ block – it runs come hell or high water, after the preceding blocks proffer their execution:

try {
  // Code that might throw an error
} catch (error) {
  // Handle the error
} finally {
  // Clean-up code, runs regardless
}

The usefulness of finally, as sturdy and expected as the rhythms of the Mississippi River, lie in its inevitability.

Summary

With the grand journey through TypeScript’s try/catch concluded, one should hoist the sails with confidence. Mentor to apprentice, let the preceding guide echo in your craftsmanship of error handling. Smooth waters or torrid, your TypeScript ships now harbor a resilience against the tempestuous errors.