Error handling in TypeScript. How to avoid exceptions.

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ม.ค. 2025

ความคิดเห็น • 19

  • @podobayka
    @podobayka 3 หลายเดือนก่อน +1

    I couldn't figure out the purpose of using neverthrow or the idea behind this approach. There was no information about it in the project repository either. Then I came across your video, and everything immediately became clear. Thank you!

    • @BeyondTypeScript
      @BeyondTypeScript  3 หลายเดือนก่อน +1

      I'm glad it was helpful! The important thing it to understand the principle, the library you use is not that important. Heck, you can implement the Result type on your own too! ;)

    • @podobayka
      @podobayka 3 หลายเดือนก่อน

      @@BeyondTypeScript Yea! You are totally right

  • @orterves
    @orterves 4 วันที่ผ่านมา +1

    Rust also has the ? syntactic sugar operator to clean up the code quite nicely, passing errors up to the caller and proceed otherwise - it'd be nice to have the same in TypeScript but at least the type checker can force you to handle the potential error before you can try to get the value
    The real downside to this approach is making sure you try catch any possible sources of exceptions, they can throw a real spanner in the works when the rest of the code is using result to avoid them - this is why I think checked exceptions are excessively maligned and are in fact a beneficial feature for robust code

    • @BeyondTypeScript
      @BeyondTypeScript  3 วันที่ผ่านมา

      Agree with both points (Rust syntax and value retrieval). There's a way to propagate an error in a type-safe manner using the result type. It's all about how we model the data structures that are used instead of the built-in exceptions. I posted a video about it just a moment ago. Let me know what you think?

  • @egorgor
    @egorgor 9 หลายเดือนก่อน +6

    Thanks for the video, completely agree on the topic. Just wanted to point out that there is no need to use a library. It's enough to return a discriminated union type like Response = { type: 'error', reason: string } | { type: 'success', data: T }

  • @xorlop
    @xorlop 4 หลายเดือนก่อน +2

    I like the idea of Either/Result types, because it clearly separates what is happy and sad path. However, I am curious your thoughts of just returning original value type and an Error? For example, safeParseInt would return int | Error vs Result.
    I have been littering code bases with this and it has proven useful, and I am actually not sure when it would be desired or wanted to return an Error type in the happy path, so I don’t see the benefit of separating the sad path out.
    Is there other benefits to wrapping in Result type I don’t see?

    • @BeyondTypeScript
      @BeyondTypeScript  4 หลายเดือนก่อน +1

      Thank you for your comment! Generally speaking, for safeParseInt there are indeed just two outcomes - either int or Error (with only one possibility for sad path - 0). So, it's okay to return int | Error.
      However, the Result type help to turn a partial function (not defined for all inputs) into a total function (defined for all inputs), by returning a value of type Result instead of int (for example). Notice that the Result type takes two generics - Result and can be constructed in two ways - Ok or Err. However, the Error generic can hold another ADT for all possible outcomes (in more complex cases). For example, a file system operation can fail for a number of reasons - all of them can be defined as an ADT (by the way, same is true for the happy outcomes). This situation would be a bit cumbersome to describe without any differentiation mechanism - int | FileNotFound | BadPath | FileLocked | Whatever. Compare this to Result. On top of that, sometimes, there are cases where your function may return int | int - but which one is which?
      All in all, I'd say that it's a good practice to stick to a single code style - either throwing exceptions, or int | Error, or Result type. Mixing them will lead to confusion in the team. However, if I have a choice, I always use the Result type. I hope it all makes sense :)

  • @coder_one
    @coder_one ปีที่แล้ว +1

    Have you had a chance to get acquainted with the "ts-belt" library? This is a library for TypeScript providing Option & Result types, but also other flavors from functional programming. And most interestingly, the source code of this library is written in Rescript! :)

    • @BeyondTypeScript
      @BeyondTypeScript  ปีที่แล้ว +1

      I didn't know about this library, thank you for sharing! But as I read ts-belt, the first thing I thought about was Rescript's Belt :) I'll give it a go.

  • @AmirLatypov
    @AmirLatypov 23 วันที่ผ่านมา

    Throw error have an advantage that it can go up by the functions stack. For example, imagine 5 levels of nested functions, and the deepest can throw an error. Without throwing errors we need to check for errors on the each level, even if these functions are trivial. With errors though, we can just catch an error on the controller, and return 500 with a message from the error itself.

    • @BeyondTypeScript
      @BeyondTypeScript  21 วันที่ผ่านมา

      Oh yeah, this debate is as old as both paradigms have existed. Imagine a large group of developers (anything above, say, 20) working on a product. Some of them may produce code that other developers will consume. Many languages do not require exception handling. As the business grows, the codebase potentially grows too (new features, old features get a facelift, etc.), and the number of developers grows. If someone introduces a new exception somewhere, the compiler will not bother. This, potentially, leads to users getting a weird error message that they have no idea how to handle and developers looking at monitoring tools trying to understand where this exception and all those 500s came from.
      Now, I understand this example is overly simplified. But this is a fun topic to explore on your own. In the end, there's a good reason why all of those libraries exist and other languages (Haskell, Rust, Go, etc.) adopt the no-exception model. Even Java now kind of went in this direction with checked exceptions.

    • @AmirLatypov
      @AmirLatypov 21 วันที่ผ่านมา

      @ I agree we need it. But there also should be an easy way to propagate error up in the stack. Rust have it.
      Java, if I remember correctly, can list all the errors type it can throw (I never used Java), etc

  • @purovenezolano14
    @purovenezolano14 4 หลายเดือนก่อน +1

    Recommend you switch to `neverthrow` as `ts-results` is unmaintained

    • @BeyondTypeScript
      @BeyondTypeScript  4 หลายเดือนก่อน

      Thank you for the suggestion! Indeed, there are lots of alternatives to `ts-results`.

  • @AndresJimenezS
    @AndresJimenezS 2 หลายเดือนก่อน +2

    try a bit Effect ts ;)

    • @BeyondTypeScript
      @BeyondTypeScript  2 หลายเดือนก่อน

      Oh, 100%. I've been keeping an eye on this for a long time.

    • @brianjmquio5156
      @brianjmquio5156 13 วันที่ผ่านมา

      @@BeyondTypeScript your channel was recommended to me probably because I was searching for Effect videos :)