Live data from Hacker News

Gopher Wrangling: Effective error handling in Go

stephenn.com

131–140 of 310 posts

Re: Gopher Wrangling: Effective error handling in Go

#131
post #77
post #32

Earlier quoted context omitted.

In what sense aren't they monads? They have a bind method ("and_then") and a return method (Which is just the variant for constructing the success case, i.e. "Ok" or "Some"). It's more idiomatic to use "map", but that's just a degenerate case of bind. > There's some tricks that have to be done to make them work in a eager evaluation context... Monads have nothing to do with laziness, though. In Haskell, IO actions ar…

After doing some research to refresh my memory I found this old thread: https://users.rust-lang.org/t/what-is-a-monad-and-who-needs-... I believe what I had originally told that makes them not monads is that because Rust goes through some convlutions to fake the laziness of Haskell monads, it makes them not be typed like Haskell monads. For example, the declaration of the `.flat_map` on an iterator is actually `fn fl…

Monads have nothing to do with laziness and we're talking about the Result type anyway.

OP is correct. If it has a bind, pure and map (which it does!) then for all intents it forms a monad.

Now the fact is you can't _manipulate_ monads in Rust easily (see kinds and discussions wrt GAT), but nonetheless monads are present in all languages with ADTs in the same way that rings are present in all languages with addition.

Re: Gopher Wrangling: Effective error handling in Go

#133

The provided examples highlight exactly why error handling in golang is verbose, error prone, and lacks context. Do people really not care about stack traces?

Less than I thought I would. I work with a very large Go codebase, and I don't remember the last time I had problems because I needed a stack trace. Just grepping for the error message is enough to show me exactly where it happened. Still, this doesn't mean that Go does not have stack traces. It does have stack traces for panics, and you can create stack traces by wrapping errors.

I also worked on a very large golang codebase, and error traces were sorely missed. Searching for the error string is not sufficient. What happens when the string changes in the master branch, which is different from the deployed version? What about when there are different code paths to get to the same error message?

I'm aware that it has stack traces for panics, but those should be rare in practice. Day to day debugging was more tedious in golang.

Re: Gopher Wrangling: Effective error handling in Go

#134
post #118

Earlier quoted context omitted.

> In Go, you are always forced by the language to return a value of type "A or B, including both or neither." The consumer isn't any more in control, it just has to guess whether "both or neither" are possible return types. it does not have to guess convention dictates either one or the other is convention enough? is it roughly the same as compiler-enforced rules? you're free to say "no" but it is not like a guarante…

>convention dictates either one or the other Convention is just an educated guess. >is it [convention] roughly the same as compiler-enforced rules? No. The answer is no. I'm not only free to say "no," but if I'm honest and truthful I am compelled to say "no."

> Convention is just an educated guess.

at some absolute level yes, but at any pragmatic level no, definitely not

> No. The answer is no. I'm not only free to say "no," but if I'm honest and truthful I am compelled to say "no."

nope! wrong. do not pass go, etc. -- it's a spectrum

Re: Gopher Wrangling: Effective error handling in Go

#135

Earlier quoted context omitted.

I frequently am sad about the kind of Rust error that doesn't have stack traces. Do you not often see something like "file not found" and need to know what file wasn't found? Or do the lowest level go error types carry more context?

The programmer needs to be aware that they will need to provide enough context in case of a failure. One thing I see a lot in Go examples is this pattern: body, err := readFile(fileName) if err != nil { return "", err } If the error returned by readFile is just "not found", it would indeed be very vague. This is still poor error handling, in my opinion, since a lot of the context is lost. Yes, they are "handling" the…

You basically end up reinventing stack traces, with all the possible ways context can be missed. This summarizes the language quite well.

Re: Gopher Wrangling: Effective error handling in Go

#136
post #91

Could someone explain why is Go so hyped? In my personal opinion it is just not a good language, and I think many judge it based on some false basis that it is somehow “close to the hardware” because it produces a binary. Like, the amount of time it is put next to Rust when the two have almost nothing in common.. It is very verbose, yet Java is the one that is called that, often by Gophers, which is much more concise…

In my personal opinion it's a great language to solve problems _I_ have to deal with in course of my work. Can I solve them with Java?

Sure.

Difference is go does not have the complexity you can find in Java and quite opinionated. So you don't have to spend as much time working with the language inself and can focus on getting the job done.

Go is not as expressive and some other languages and does not have the same abstractions that make other languages more suited to be used while developing comlex software.

Thing is - in many cases you simple do not need any of it, but need a fast verbose language with good tooling.

Call it Java Light or something.

Re: Gopher Wrangling: Effective error handling in Go

#137

Earlier quoted context omitted.

How does it address it? By making it painstakingly verbose (not to mention error prone) to deal with errors? Not referring to you personally, but I've heard that sentiment several times now, and I have not seen anything to back it up (as with several other golang claims).

given a function fn that can fail, it will return a result and an error e.g. result, error = fn(...) calling this function should yield to the caller two possibilities, somehow: a success value _or_ a failure error the important thing is that in both cases, the control flow is visible in the source code as written result, error = fn(...) if there was an error, ... if it was successful, ... when an expression fails, y…

Nothing is preventing the code from returning both at the same time. I've seen code (including in the standard library) that returns both an error and a return value. In a language with disjoint unions, such cases would be encoded properly.

Re: Gopher Wrangling: Effective error handling in Go

#138
post #55

Earlier quoted context omitted.

How does it address it? By making it painstakingly verbose (not to mention error prone) to deal with errors? Not referring to you personally, but I've heard that sentiment several times now, and I have not seen anything to back it up (as with several other golang claims).

with robust and potentially high volume code, the most important feature is good behavior in failure domains. disk full, do you abort or continue once the cron job frees some space; cant alloc memory, do you abort or return a static 503 page? bad contents in some file, do you exit or log the error and carry on? does a bad pyc file generate a good error message or crash python. this robustness is the famed second 90%…

Nothing you wrote is specific to golang's error handling though, and in actuality, ends up being more brittle because it is possible to miss handling such errors. At least an exception would bubble up instead of keeping the program running in an undefined state.

Re: Gopher Wrangling: Effective error handling in Go

#139
post #91

Could someone explain why is Go so hyped? In my personal opinion it is just not a good language, and I think many judge it based on some false basis that it is somehow “close to the hardware” because it produces a binary. Like, the amount of time it is put next to Rust when the two have almost nothing in common.. It is very verbose, yet Java is the one that is called that, often by Gophers, which is much more concise…

https://en.wikipedia.org/wiki/Worse_is_better Go is a language made by Googlers, so its design helps with Google problems. And many of Google's problems are ones of scale. * Go is straightforward to read. Any reasonably-competent college graduate should have little trouble understanding it and be able to become productive quickly. * Go compiles into completely static binaries. You don't have issues like "oops, the bu…

Yet, the bulk of code written at Google remains Java and C++. golang's approach to uncolored async was decent, yet in the same manner of the language, overly verbose and error prone. Passing channels everywhere gets tricky quickly, and you have to manually ensure that contexts and deadlines are handled everywhere.

Errors in golang do not have stack traces, and wrapping errors is just an error prone way of manually (and apparently nonperformant way of) generating stack traces.

Re: Gopher Wrangling: Effective error handling in Go

#140
post #118

Earlier quoted context omitted.

>convention dictates either one or the other Convention is just an educated guess. >is it [convention] roughly the same as compiler-enforced rules? No. The answer is no. I'm not only free to say "no," but if I'm honest and truthful I am compelled to say "no."

> Convention is just an educated guess. at some absolute level yes, but at any pragmatic level no, definitely not > No. The answer is no. I'm not only free to say "no," but if I'm honest and truthful I am compelled to say "no." nope! wrong. do not pass go, etc. -- it's a spectrum

>nope! wrong. do not pass go, etc. -- it's a spectrum

You are simply incorrect, there's no nuance or room for interpretation. A compiler can guarantee "A or B, but not both or neither", "A or B or both, but never neither", or even "A or B or both or neither" but convention for (A, B) in Go cannot, therefore it is not as good. Go's conventions are not as good as a decent type system, there's no spectrum about it; Go is always "A or B or both or neither" with no ability to exclude impossible/nonsense cases. In Go if I want to write robust, correct code I must always handle all 2^N cases for N arguments, which no one actually does.

Post reply on HN