News for hackers. Stuff that matters.
Re:Go proposal: Leave “if err != nil” alone? by madrox on Friday June 28, 2019 @12:42PM (#20306192)
I've only just started using Go (coming from Python), and I find the existing error pattern cumbersome. It often gets in the way of understanding the function at hand. I think the intention behind the existing pattern is to not over-emphasize the happy path and ensure error conditions are dealt with so programs don't crash, but 99% of the time all I see error handling do is just print the error and then return.

There has to be a better way.

Re:Go proposal: Leave “if err != nil” alone? by dkarl on Friday June 28, 2019 @01:26PM (#20306705)
My experience reading and modifying Go applications has been similar. It often feels like at some point the person writing the code experienced error handling fatigue and all the error cases started blurring together. Every possibility gets explicitly handled, which is impressive, but important common cases that should be a carefully designed part of the system get the same perfunctory treatment as the weird edge cases. Go systems are the only systems I've worked with where silent failures are the most common kind of bug. "But it isn't a silent error; it's in the log and triggered an alert!" Yes, but our customers don't get our alerts. They just get 200s that they don't trust anymore.

It makes me think Go's comprehensive error handling can be compared to the performance of C. If you need it, it's great; if you don't need it, the effort you invest in it will detract from something you do need.

Re:Go proposal: Leave “if err != nil” alone? by ramenmeal on Friday June 28, 2019 @01:08PM (#20306507)
What I worry is that this problem is overhyped from new go coders (or people who took a look at go and that's it). The explicit error handling blends into the background so fast. It's never been an issue for me while developing in the past 4 years on go based systems.
Re:Go proposal: Leave “if err != nil” alone? by KirinDave on Friday June 28, 2019 @01:25PM (#20306691)
This is the real danger of the pattern, isn't it? It fades into the background, lulling your eyes into skipping over what's potentially a major source of bugs.
Re:Go proposal: Leave “if err != nil” alone? by tptacek on Friday June 28, 2019 @05:54PM (#20309069)
It's hard to believe an explicit error check could be more lulling than the invisible exceptions most mainstream languages use.
Re:Go proposal: Leave “if err != nil” alone? by kazinator on Saturday June 29, 2019 @02:47AM (#20311154)
Error return values are also invisible.

By default, an ignored return code does nothing. The situation is shuffled under the rug.

By default, an ignored exception is loud.

Error codes have to be handled to become louder.

Exceptions have to be handled to become quieter.

The control flows underlying exceptions are syntactically invisible except at the source and destination sites. However, they reliably occur. They reliably occur because they are invisible. If exceptions had to be propagated by some visible assistance through all the layers they cross, they would become unreliable.

The problem/trade-off with exceptions (the bad aspect of how they are invisible in their own way) is that if we have statements like S1; S2; S3, we can never be sure that S2 is reached, or if S2 is reached then S3. S1 can call some function that throws, and so can S2 or S3.

Exceptions can cause partially executed statement flows to be unexpectedly abandoned. And that means that whatever those statements were doing remains half done because the programmer assumed that if S1 is reached, then S2 and S3 are an iron-clad given.

Programmers using exception-based languages have to train themselves to use unwind protection mechanisms in all situations fitting the pattern that "if we have executed S1, then S2 must execute to complete/undo/clean-up whatever S1 started". They must never rely on ordinary sequencing, except when it is obvious that the code doesn't throw (for whatever reason: triviality, or all being in the same module put together by that programmer or whatever). If any external code is involved (statements inserted by a macro, foreign callbacks, calls into third party stuff), all bets are off.

Re:Go proposal: Leave “if err != nil” alone? by tptacek on Saturday June 29, 2019 @02:20PM (#20313970)
That wasn't the argument Dave made. He said that handled error returns became invisible, because the repetition lulled programmers. That's the argument I felt was untenable.

Obviously, Go does some things to mitigate the risk of ignored error returns; the damnable use requirement means that multi-valued functions returning errors either have to explicitly ignore the error by assigning it to "_", which feels as squicky as it should, or be assigned to a variable with which (usually) something must later be done.

It's not perfect, I'll freely concede.

Re:Go proposal: Leave “if err != nil” alone? by KirinDave on Saturday June 29, 2019 @05:33PM (#20314917)
They.
Re:Go proposal: Leave “if err != nil” alone? by tptacek on Tuesday July 09, 2019 @06:55PM (#20397580)
Sorry! I'll be more careful.
Re:Go proposal: Leave “if err != nil” alone? by KirinDave on Friday June 28, 2019 @06:06PM (#20309147)
The thing is, a lack of error handling code is a clear sign of deferral. No action is a "pass" up the stack, ultimately to the top loop. In Go, a lack of action is called out, but the policy for pass/keep is explicit on every choice and sometimes can be subtle (for examples of you try to do an http call expecting an error, that looks nearly identical to code that does the opposite.

I think that the try() stuff removing the humdrum repetition is a good idea precisely because it makes all explicit error handling stand out like a beacon. I might name it "pass" or something but that's not as important. If I recall correctly, it vaguely resembles a solution you recommended to me on at least one occasion.

Keeping things as they are seems to me like the worst possible option.

Re:Go proposal: Leave “if err != nil” alone? by tptacek on Friday June 28, 2019 @07:12PM (#20309583)
I understand your argument and it is coherent, but it isn't persuasive. Yes, you can treat lack of error handling as a clear sign of deferral. In practice, that is not how people treat a lack of error handling.

I agree that "try" is better than the status quo, not because the if statements are lulling, but because they have the effect of triple-spacing Go code and making it harder to read.

Re:Go proposal: Leave “if err != nil” alone? by KirinDave on Friday June 28, 2019 @11:44PM (#20310699)
> I understand your argument and it is coherent, but it isn't persuasive. Yes, you can treat lack of error handling as a clear sign of deferral. In practice, that is not how people treat a lack of error handling.

To be honest I'm not sure what you're suggesting at all. The reason the default error handling strategy for so man languages is to defer upwards is because that's by far the most convenient behavior for development, and is not the worst decision in prod.

Folks don't seem to find it confusing. Their programs crash with a stack trace. Certainly exception propagation has its own issues, but the default strategy isn't a thing I'd call out as bad. Indeed, if anyone can't produce a good crash-to-stack (cough, Haskell, cough) they get called "unfriendly" for developers.[1]

Meanwhile, I'm hardly the only voice in the choir of folks saying that Golang's error handling is frustratingly repetitive and can sometimes introduce surprising issue due to variable reuse, capture and shadowing.

> I agree that "try" is better than the status quo, not because the if statements are lulling, but because they have the effect of triple-spacing Go code and making it harder to read.

Both of these can be true without invalidating each other.

[1]: This is not to say we can't do better. Common Lisp is quite rightly famous for its Conditions and Restarts which are (imo, of course) pretty much the best error handling system ever created, allowing developers to embed recovery strategies AND rich exceptions in their code with syntactically and semantically obvious constructs and then pass the calling code the responsibility of choosing a mitigation strategy (or crashing).

Re:Go proposal: Leave “if err != nil” alone? by kasey_junk on Friday June 28, 2019 @09:10PM (#20310145)
What I’m curious about is how it will impact shadowing bugs which are the most common I see in practice.

My intuition is it will alleviate that but I’m not sure.

Re:Go proposal: Leave “if err != nil” alone? by tylerFowler on Friday June 28, 2019 @02:39PM (#20307524)
Not more than seeing that an existing function you're extending or otherwise working on throwing its exceptions and saying "Ok I guess something above this will catch my exceptions" and learning to take that at face value. Or at least that's been my experience working on large scale Java projects with teams.

From my experience with Go I find that only these lines fade into the background: something, err := someFunc() if err != nil { return nil, err }

I find that whenever any actual error handling logic beyond forwarding tends to really jump out at me in code reviews and such.

Re:Go proposal: Leave “if err != nil” alone? by mav3rick on Friday June 28, 2019 @01:14PM (#20306573)
Rust provides really good syntactic sugar that doesn't compromise on catching errors. I get Go is inspired by C, but sometimes it seems too stringent on avoiding any and everything that may make life easier for readers and programmers.
Re:Go proposal: Leave “if err != nil” alone? by crimsonalucard on Friday June 28, 2019 @01:16PM (#20306600)
You're use to using a hammer on a screw. It's never been an issue for you for four years.

It's still a big issue overall.

Re:Go proposal: Leave “if err != nil” alone? by xmprt on Friday June 28, 2019 @01:24PM (#20306685)
You're exactly the problem the commenter is talking about. I got used to it within a month and while I would appreciate better error handling (if that even exists), I don't think the solution should be rushed and I don't think the way Java handles it is right.
Re:Go proposal: Leave “if err != nil” alone? by crimsonalucard on Friday June 28, 2019 @01:38PM (#20306831)
I agree, but leaving it because people are used to it is not the right solution imo.
Re:Go proposal: Leave “if err != nil” alone? by marcrosoft on Friday June 28, 2019 @12:48PM (#20306258)
> all I see error handling do is just print the error and then return.

Yeah, that is a problem. At least they had to manually type it out and (maybe) think about how to handle the error during that time. To streamline this is to further exacerbate the issue. They will do a try/catch try/defer `log.Println`.

With Python try/catch allows for ultimate laziness. It allows for 1,000 line try/catch blocks that can hide/capture errors that bubble up from anywhere. Of course this is bad development but it's possible. Currently with Go it is impossible to forget about error handling. You have to consciously make a choice on what to do with it. Even if that choice is to log/print it out.

Re:Go proposal: Leave “if err != nil” alone? by msbarnett on Friday June 28, 2019 @12:59PM (#20306380)
> Currently with Go it is impossible to forget about error handling.

You’re describing some other language that forces you to deal with errors, like Haskell or Rust.

A bare

    io.WriteString(w, “ok”)
will happily compile despite returning a completely unhandled error.
Re:Go proposal: Leave “if err != nil” alone? by xmprt on Friday June 28, 2019 @01:26PM (#20306704)
Meanwhile code like

    a, b := someFunc()
    fmt.Println(b)
throws a compiler error like it's the end of the world if you define a variable that isn't used.
Re:Go proposal: Leave “if err != nil” alone? by pstuart on Friday June 28, 2019 @02:07PM (#20307173)
If you can type "a, b :=", you can type "_, b :=".

It's not a big deal.

Re:Go proposal: Leave “if err != nil” alone? by saghm on Friday June 28, 2019 @02:37PM (#20307488)
When I wrote Go at work, this would mostly be annoying when interactively writing and running code; if I want to comment out the only line below that uses `a` and run it again, now I have to go back and change the declaration also. Once I want to to run that line again, I can't just uncomment it; I have to go back and declare it again. I would have to do stuff like this fairly often when trying to debug failed tests, so despite the fact that I'd never want to _commit_ code with an unused variable, I certainly would like to be able to _run_ it when debugging. I feel like a warning is definitely better than a hard error here; it's pretty easy in most languages with warnings to set up CI to reject unused variables, which ensures that your code in production won't have any unused variables.
Re:Go proposal: Leave “if err != nil” alone? by pstuart on Friday June 28, 2019 @06:06PM (#20309152)
Understood. I think the problem is that once options like that are given they become abused and eventually institutionalized.

A quick work around for that example would be to a line: `b = b`.

Go vet complains but it builds and runs.

Re:Go proposal: Leave “if err != nil” alone? by apta on Friday June 28, 2019 @02:21PM (#20307324)
> Currently with Go it is impossible to forget about error handling.

Not true at all. The easiest example is:

  func main() {
      fmt.Println("")
  }
The error is not being handled. An exception-based language doesn't have this issue, neither does a language that actually forces you to handle errors.
Re:Go proposal: Leave “if err != nil” alone? by lgunsch on Friday June 28, 2019 @12:55PM (#20306339)
I once code-reviewed a serious bug-fix, in Python, causing leaking threads to crash a server. The bug turned out to be a bare try-except hiding a function call with a missing argument; 2 args passed instead of 3. Not exactly a syntax error, but pretty close.
Re:Go proposal: Leave “if err != nil” alone? by crimsonalucard on Friday June 28, 2019 @01:19PM (#20306623)
the Golang way breaks function composition to make error handling a bit more explicit.

There are actually better ways. Rust and Haskell not only fix this problem without breaking function composition... they make it so that the compiler is able to catch missing error handling logic.

The golang way of doing this is not the ideal way, but it does fix your issue with python.

Re:Go proposal: Leave “if err != nil” alone? by dec0dedab0de on Friday June 28, 2019 @12:58PM (#20306374)
Many times I've had to say NO DONT DO THAT! to people writing giant try/except blocks in Python.

Usually the answer is to wait for an actual exception and if it's not something you could actually anticipate, then write a tiny try block that just handles the exception. The whole point being that I want it to fail if there is an unknown exception. Which in Go, you wont fail at runtime if you are just printing errors as a habit( I think, I have not done much with go).

That said, a lot of times it makes sense to return errors, and perhaps there in lies the difference between an exception and an error.

Re:Go proposal: Leave “if err != nil” alone? by superbaconman on Saturday June 29, 2019 @08:49AM (#20312289)
Massive try catch statements introduce excessive indentation, and moves the handling logic away from what's being handled. It's hard to believe that this would be common practice among anyone with a few years under the belt.
Re:Go proposal: Leave “if err != nil” alone? by eweise on Friday June 28, 2019 @12:48PM (#20306253)
I like how Kotlin and Scala just let the errors bubble up to a level that cares. The code looks very clean and its clear where the error handling is.
Re:Go proposal: Leave “if err != nil” alone? by dkarl on Friday June 28, 2019 @02:34PM (#20307457)
I really like this as well for most applications. You code the happy path and the errors that are part of the product behavior, error handling code is located where it makes sense, and unhandled exceptions get lumped into a catch-all error, such as 500 for an HTTP request. "finally" blocks take care of resources. It really hits a sweet spot for stability and honesty for applications like web services.

I get that Go is targeting a systems niche where error handling is more sensitive. I think there will be fewer complaints about Go's error handling when people get a better sense for when to use it.

Re:Go proposal: Leave “if err != nil” alone? by ernst_klim on Friday June 28, 2019 @05:03PM (#20308767)
IMHO the worst part of Go errors is that they are strings, so if you propagate them, you can't do anything but print them. You can't handle them properly, since you can't match them in a robust way.

Just compare how good the error handling is in OCaml: http://keleshev.com/composable-error-handling-in-ocaml

Re:Go proposal: Leave “if err != nil” alone? by alphabettsy on Friday June 28, 2019 @07:52PM (#20309816)
Huh? They’re not strings. They’re an interface and you can create your own error type that implements the error interface, one of the requirements being that it has a string output available.
Re:Go proposal: Leave “if err != nil” alone? by ernst_klim on Saturday June 29, 2019 @04:24AM (#20311448)
>They’re not strings.

They are strings. They are implementation of interface with a single `to_string` method, after you got `error`, you can't say (you could use switch on type, but you should guess which type could it be), so basically you have an opaque object with a single `to_string` method, which is equivalent to string.

I can't fancy a more error prone way than that which Go choose. How you match the errors, you match strings? You match types? You don't even know what types could there be, since all what the type system says is that function returns error.

Re:Go proposal: Leave “if err != nil” alone? by slx26 on Friday June 28, 2019 @01:01PM (#20306413)
yeah, I kinda agree. at least in Ruby, besides the errors bubbling up, if you had to handle the error manually, you could use the truthiness of the language to write just:

   do_something if err
I've read the other proposals, and in fact one of them (catch) is similar to what I do when I'm coding just for myself:

   value, err := os.Open(filename)
   exit_on_error(err)
where the code for exit_on_error is simply something like:

   if err != nil { 
      fmt.Println("Something went wrong!")
      os.Exit(1) 
   }
you could make it a bit more robust:

   value, err := os.Open(filename)
   handle_error(err, ERROR_FILE_OPEN)
where ERROR_FILE_OPEN could be a simple constant, and in the method we have a switch with constants and messages. not a zero cost abstraction, but if you have to handle an error, it probably wasn't a cheap operation either, so the extra call won't be an issue
Re:Go proposal: Leave “if err != nil” alone? by basic6 on Friday June 28, 2019 @01:28PM (#20306730)
Go's opinionated, three line if is part of the problem. A single line if or ternary operator would reduce the line noise.
Re:Go proposal: Leave “if err != nil” alone? by __david__ on Friday June 28, 2019 @01:54PM (#20307025)
Yeah, it's quite common in C to just do:

    if (error) return error;
It's the same style as go, but so much more compact. If `go fmt` were to render the error boilerplate as

    if err { return err }
…instead of the three line boilerplate it insists on, then it would go a long way.

That said, I still support `try()`. It looks good to me, especially coming from Rust.

Re:Go proposal: Leave “if err != nil” alone? by NelsonMinar on Friday June 28, 2019 @01:03PM (#20306431)
Language support for exceptions are the better way.
Re:Go proposal: Leave “if err != nil” alone? by marcrosoft on Friday June 28, 2019 @01:24PM (#20306679)
Go is successful and popular because it is different from other languages. Most languages have exceptions and from a Go developer's point of view they are terrible.
Re:Go proposal: Leave “if err != nil” alone? by apta on Friday June 28, 2019 @02:24PM (#20307368)
This is a non-argument really. Someone can easily say that so many things from a non-golang developer's point of view about golang are badly designed.
Re:Go proposal: Leave “if err != nil” alone? by AnimalMuppet on Friday June 28, 2019 @04:01PM (#20308294)
Yes and no. "Go users like it" does not imply "therefore it's good", just as "Non-go users don't like it" does not imply "therefore it's bad".

But "Go users like it" does imply "therefore it's not too badly mismatched to what go users are trying to do with it". Likewise, "Non-go users don't like it" implies "therefore it probably isn't a perfect fit for what non-go users are trying to do".

Re:Go proposal: Leave “if err != nil” alone? by gigatexal on Friday June 28, 2019 @12:47PM (#20306242)
Once you get used to it it’s not that bad. Editors make a macro of it so you hardly ever type it out.
Re:Go proposal: Leave “if err != nil” alone? by erik_seaberg on Friday June 28, 2019 @12:52PM (#20306301)
Generating boilerplate is easier than reading it over and over. We need an IDE than can at least hide it and focus on the 1/4 of the lines that do something.
Re:Go proposal: Leave “if err != nil” alone? by convolvatron on Friday June 28, 2019 @01:29PM (#20306740)
its a bit of a drag. one niggling thing is that if, should it return a zero value along with the nil, means you have to be explicit about which zero value you are using..so refactoring function return types involves touching each of these.

not the end of the world, just sad. i do wish there were a type-unified zero value, or that "" and 0 were the same as nil, or some other solution here

Re:Go proposal: Leave “if err != nil” alone? by gigatexal on Friday June 28, 2019 @01:50PM (#20306978)
Yeah I have a function like this: return a *struct, err where a nil struct could be the result of a empty result from the database query that was just run or an error if the query had an error. And then the logic of that function is if a job was returned quit early (I’m preventing two things from happening on the DB side). But then there’s an annoying dance of checking if the job is nil and the error is nil that’s the happy path... you can see how this makes the just if the check err is nil usual path welcome