DEV Community

Noah
Noah

Posted on

No more Try/Catch: a better way to handle errors in TypeScript

Hello everyone.

Have you ever felt that Try/Catch is a bit inconvenient when developing an application in TypeScript?

I luckily found an amazing video on YouTube that describes how to handle errors in TypeScript in a simple way.
I'm sharing insights from the video as a review.

Defining the getUser function for error handling

First of all, I defined a simple getUser function to illustrate error handling.
It returns a new user with the given id.

const wait = (duration: number) => {
  return new Promise((resolve) => {
    setTimeout(resolve, duration);
  });
};

const getUser = async (id: number) => {
  await wait(1000);

  if (id === 2) {
    throw new Error("404 - User does not exist");
  }

  return { id, name: "Noah" };
};

const user = await getUser(1);

console.log(user); // { id: 1, name: "Noah" }
Enter fullscreen mode Exit fullscreen mode

Error Handling using try/catch

Rewriting the previous code using try/catch, it looks like this.

const wait = (duration: number) => {
  ...
};

const getUser = async (id: number) => {
 ...
};

try {
  const user = await getUser(1);
  console.log(user); // { id: 1, name: "Noah" }
} catch (error) {
  console.log("There was an error");
}
Enter fullscreen mode Exit fullscreen mode

Problem with try/catch ①: It handles every error that occurs within the try block

The code below is not ideal.
Even though it's just a typo, "There was an error" is displayed in the console. I only want to handle errors that occur specifically in getUser within this try/catch block.

const wait = (duration: number) => {
  ...
};

const getUser = async (id: number) => {
 ...
};

try {
  const user = await getUser(1);
  console.log(usr);               // ← There was an error
  // ... (a lot of code)
} catch (error) {
  console.log("There was an error");
}
Enter fullscreen mode Exit fullscreen mode

Problem with try/catch ②: The Pitfall of Using let

Okay then, let's try to solve it using let.

const wait = (duration: number) => {
  ...
};

const getUser = async (id: number) => {
 ...
};

let user;

try {
  user = await getUser(1);
  // ... (a lot of code)
} catch (error) {
  console.log("There was an error");
}

console.log(usr); // ← ReferenceError: Can't find variable: usr
Enter fullscreen mode Exit fullscreen mode

I got an actual error from the typo, but this code is still not ideal because I can accidentally redefine the user object, like below.

const wait = (duration: number) => {
  ...
};

const getUser = async (id: number) => {
 ...
};

let user;

try {
  user = await getUser(1);
  // ... (a lot of code)
} catch (error) {
  console.log("There was an error");
}

user = 1 // ← ❌ It might lead to a bug.
Enter fullscreen mode Exit fullscreen mode

Ideal solution

It's much simpler and more readable, don't you think?
Furthermore, the user variable is immutable and won't lead to unexpected errors.

const wait = (duration: number) => {
  ...
};

const getUser = async (id: number) => {
 ...
};

const catchError = async <T>(promise: Promise<T>): Promise<[undefined, T] | [Error]> => {
  return promise
    .then((data) => {
      return [undefined, data] as [undefined, T];
    })
    .catch((error) => {
      return [error];
    });
};

const [error, user] = await catchError(getUser(1));

if (error) {
  console.log(error);
}

console.log(user);
Enter fullscreen mode Exit fullscreen mode

Conclusion

By using this function for error handling, we can significantly simplify our code and make it cleaner and easier to maintain. Instead of scattering multiple "try/catch" blocks throughout the code, this approach keeps our error handling consistent and less noisy. It’s a smarter, more efficient way to manage errors in TypeScript.

Please take a look at the video, which we have referenced. He explains it very carefully.
Happy Coding☀️

Top comments (1)

Collapse
 
programmerraja profile image
Boopathi

This is a great breakdown of the limitations of try/catch and a more elegant solution for handling errors in TypeScript. The catchError function looks incredibly useful for maintaining clean and readable code.