2021-08-09
1809
#typescript
Alain Perkaz
62489
Aug 9, 2021 ⋅ 6 min read

Improving TypeScript error handling with exhaustive type checking

Alain Perkaz A passionate and disciplined software engineer.

Recent posts:

Making Your First Game In Excalibur.js

Game development for frontend: Building with Excalibur.js

Build your first 2D browser game using JavaScript and the Excalibur.js library, covering essential game development concepts.

Yashodhan Joshi
Apr 3, 2025 ⋅ 25 min read
angular vs react

Angular vs. React: Which one should you choose?

Explore the key differences between Angular and React, their strengths, and use cases to help developers decide which option to choose.

Oscar Jite-Orimiono
Apr 2, 2025 ⋅ 5 min read
axios in javascript

Axios in JavaScript: How to make GET, POST, PUT and DELETE requests

Learn how to use Axios in JavaScript for GET, POST, PUT & DELETE requests. Examine setup, error handling, and API best practices.

Faraz Kelhini
Apr 1, 2025 ⋅ 19 min read
how AI is shaping the future of 3D web development

How AI is shaping the future of 3D web development

AI for 3D web development is taking the internet by storm. Learn about this trend, the best tools for 3D web experiences, and how it’ll affect the development landscape moving forward.

Elijah Asaolu
Apr 1, 2025 ⋅ 5 min read
View all posts

3 Replies to "Improving TypeScript error handling with exhaustive type checking"

  1. There are 3 issues with what’s being proposed in this article:

    1. Having too many try/catch blocks everywhere isn’t necessary, and is usually a code smell. Errors need to be caught usually only when we need to “wrap” an error (i.e. bubble up a different kind of error type or message) and once at the top level as a generic way to catch unhandled errors and alert the user in a friendlier way than crashing the app.

    2. The “it catches all the errors without distinction” argument is only a problem if you’re not checking the error type in the catch block. If you have distinct types of each error, distinguishing between them is as simple as doing `if (error instanceof MyCustomErrorType)` to check for it and doing something, and just doing `else throw error` if it’s any other error to bubble it up.

    3. The “Result” pattern is fine in other languages like Rust or Go where it’s a first-class citizen of the language, but it doesn’t make sense in TypeScript/JavaScript simply because “Result” types aren’t a native construct and starts feeling unnatural and verbose after a while, when just knowing how to throw and catch errors properly works just fine, is less verbose, and is tightly integrated into the language.

    1. The `Result` pattern is definitely not the only way, and in small or simple apps try/catch may be enough.

      In order to effectively check the error types, you have to manually go into all the functions that are called in a given try block (and all the nested functions). A project-wide error convention may mitigate this, but it doesn’t solve the issue of needing to perform manual checks. By using the pattern, all the returns of a function are typed, not only the happy path.

      At the end of the day, this pattern makes the error flows explicit and typed, which is not supported by the built in try/catch. Verbosity is a subjective topic, there are plenty of libraries that expose a terser API: https://github.com/swan-io/boxed

      Finally, this pattern is already in use by built in JS APIs, such as the Fetch API (using the Response class). The post adds extra ergonomics by leveraging TypeScript.

  2. Some false examples in the demo code.

    Rule: Only throw an exception if the method can not handle the error.

    If the method can handle the error, great; else, allow the exception to naturally go up the chain until something can address the problem.

    Rule: Never double-log an error/exception.

    Double-logging is a common problem in event management where the same error is seen all through the logs. The only code that should be logging the problem is the code that deals with the exception.

    Conclusion: Following the basic rules will clean up the code and the log files and eliminate the need for the Result class/data.

Leave a Reply