4 ms·
I’ve taken Go’s approach to error handling in new typescript projects. I want to force my team into thinking about IO errors. I want failures to be part of the
by virmundi 7y ago
I’ve taken Go’s approach to error handling in new typescript projects. I want to force my team into thinking about IO errors. I want failures to be part of the domain since stack traces only kinda work in Node. We will only throw exceptions if someone didn’t program for bulls properly. Everything else is a Failure instance passed up the call chain. Annoying, but our testing and code-thoughtfulness have gone up.
- bitwize 7y agoGo handles it shitty, like the past five decades of computer science and PL design never happened. For imperative languages, exceptions are perfectly fine as a way to encode failure as part of the domain of operations. If you're in functional fantasy land, the correct approach is to use a Maybe monad or, better yet, an Either monad. But Go supports neither of these and that's one of many reasons why it sucks for modern development. In TypeScript you can do better and, for the sake of others who have to maintain your code, you should do better.
- pixelrevision 7y agoThe biggest mistake I think go made was not to include codes or domains. The error you get back is... a string. So you have to write tons of if statements just to return a bunch of errors you can’t handle.
- donatj 7y agoError is an interface. The default one may be a string but you can implement your open error with whatever extras you would like.
- CameronNemo 7y agoRight but then you need to use errors.as to match against it, rather than being able to do pattern matching. And there is no inheritance, no ability to generalize errors into a group.
- donatj 7y agoYou can totally just type assert your custom error type to check for it. If it's the only type of error your method returns you don't even need to, just define your return type as your custom error type.
- QuinnWilton 7y ago> Go handles it shitty, like the past five decades of computer science and PL design never happened. This has generally been my complaint with Go. Go is... fine. It offers a lot of features that seem revolutionary if you've never seen them before, but mostly feel like someone took the best parts of every language, and then implemented the least interesting aspects of those features. - Interfaces are like typeclasses, but without actually offering any sort of higher-kinded polymorphism. - Goroutines are kind of like Erlang processes, but without any notion of supervision and with shared mutable state. - The error handling feels like it's trying to emulate an Either monad, but in a way that doesn't actually allow for the compositional properties that make an Either monad useful. I know that Go's goal was never to innovate on language design, but I feel like it ignored a lot of low-hanging fruit in modern language design. Obviously you can do worse than coding in Go, but for everything Go is good at, there's likely an even better tool for the job. I'm not convinced that there's any domain where Go is the best choice available, but it's definitely average at most jobs, and maybe that's where it finds its niche. Edited: I had missed the word "higher-kinded" in front of polymorphism. Thanks donatj!
- donatj 7y ago> Interfaces are like typeclasses, but without actually offering any sort of polymorphism Can you explain what you mean by this? I certainly use them in a manner I would consider polymorphic.
- QuinnWilton 7y agoYou're completely right; I accidentally dropped the word "higher-kinded" in front of polymorphism. Go's interfaces provide structural typing, which offers polymorphism over values. Typeclasses in comparison, offer polymorphism over types themselves. The distinction is subtle, but it drastically limits the sorts of abstractions that you can write with Go. In Go's defence, this is a limitation that even functional languages like F# and Elm face too. This sort of polymorphism is what makes ideas like monads and functors so powerful in a language like Haskell, and what causes those same ideas to lose some of their lustre in a less expressive language. Unfortunately it's really difficult to find good articles on higher-kinded types, since anything written about them already assumes a ton of knowledge about the subject. This StackOverflow thread has some good insight though: https://stackoverflow.com/questions/21170493/when-are-higher-kinded-types-useful https://stackoverflow.com/questions/21170493/when-are-higher... It's entirely likely that in the real world these sorts of limitations don't actually matter, but my general frustration with Go stems from the fact that it's so close to being so much better than it is, and it saddens me that we as an industry chose to be so excited by something that's a tiny step forward, when there exist so many other options that are entire leaps and bounds forward.
- danenania 7y agoUsing a Maybe type sounds a bit better, but not really that different than how Go does it in practice. The key decision is whether to throw errors or return them. Go's approach and the Maybe type are both variations on returning them. The problem with returning them is it's tedious and you end up with error checking boilerplate everywhere. The problem with throwing them is they're easy to ignore, and also you never know whether or not a function is capable of throwing an error, or what types of errors it can throw. In conclusion, error handling sucks no matter how you do it :-/
- smabie 7y agoYeah, it does, but using monads to fold over errors is a lot nicer than what you have to do with Go.
- ramzeus 7y agoMy experience with Go have been very positive. Once you get over the initial irritation of the error handling, I think it works perfectly fine. I have never been so productive as I can be when programming in Go. I’m sure there are technically better alternatives, but it has a very good balance between features, speed, standard library and multi platform support. At least for the backend server tasks I use it for. My biggest complaint has more to do with the new module system and tooling. The (not so) new Go Language Server is still very buggy and almost unusable in my opinion.
- jrimbault 7y agoTypeScript is equipped for having and handling option (maybe) types (`T | null`) or result (either) types (`T | Error`), why not handle errors in a proper way ? A way the compiler ensures you handle all cases in every cases ? If you do it the go way, I assume every fallible functions returns something like `[T, Error]` ? With no guarantees the error is actually checked.
- Avi-D-coder 7y agoI disagree with you, but your comment should not have been down voted so I up voted.
- fetbaffe 7y agoI used to be in exception camp, but I have lately turned to the anti-exception camp. Exceptions have a nasty way of polluting your architecture, they live orthogonal to the rest of the system but still part of the API and have a tendency to mess with every part in every layer & module. With exceptions is it easy to end up in a situation where your model code changes UI behavior. Let say your model throws ItemNotFoundExcpetion, are you going to catch that in your global handler & return a 404? The proper way is probably to catch it in your controller & rethrow a ResourceNotFoundException to the UI. Thus you need to do that for every exception, catch & rethrow. And not only you need to translate exceptions between layers & you probably want to translate exceptions between modules. The number of exception classes in your project starts to explode. You have to create hierarchies and groups of exceptions. And many of them are just copies of others. In a PHP project I experimented with a similar approach as Go, unfortunately PHP does not a have good tuple type support. You can return an array from a function, however the items will be untyped so you have to rely on phpdoc. What I did instead was to use an out variable for the error. function parseInt(string $value, ?string &$error): ?int; $int = parseInt('10', $error); if ($int === null) { echo $error; } Worked pretty okay. Still undecided if this is a good approach.
- jrimbault 7y agoIt's a classic approach in some C codebases (Sun I think used it extensively ?). My gripe with it is (only for php), it's not visible from the calling side that we are passing a pointer.
- fetbaffe 7y agoAgree, lets hope this rfc gets approved. https://wiki.php.net/rfc/explicit_send_by_ref https://wiki.php.net/rfc/explicit_send_by_ref https://externals.io/message/108699 https://externals.io/message/108699