Live data from Hacker News

Gopher Wrangling: Effective error handling in Go

stephenn.com

261–270 of 310 posts

Re: Gopher Wrangling: Effective error handling in Go

#261
post #175

Earlier quoted context omitted.

It is frustrating to read Java code. I don't want to understand your abstractions or class definitions like final, static and whatever. I don't want to learn about Gradle or Maven to understand how a package is working, I'd rather do it in code. Consider even the current "Hello, world" example in Java (Yes, I know about the proposal about simplifying it), it is tedious, why would I need to understand public/private a…

A number of years ago, I decided to try out this Java monster. Figured I'd add it to the tool belt. Opened the first hello world tutorial Google game me. It started with xml files to define string content. I noped out.

It sounds you're conflating an older framework with Java the language.

Re: Gopher Wrangling: Effective error handling in Go

#262

Earlier quoted context omitted.

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.

convention prevents it and in the case where returning both is OK, then documentation makes that clear this is not difficult

We all know that documentation always 100% matches the behavior of the code :-)

Re: Gopher Wrangling: Effective error handling in Go

#263
post #163

Earlier quoted context omitted.

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

IME, it's stack traces that miss all the context. So an error occurred 20 levels down? What was it doing? With what?

You can see the path that was taken to get to those 20 levels. Without stack traces, you're left to manually peruse the code base to figure all those out.

Re: Gopher Wrangling: Effective error handling in Go

#264

Earlier quoted context omitted.

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 debu…

You will only have problems with the same error message if they are in the same function, otherwise the wrapped errors will show a different path. It is possible, but they will be close to each other. Stack traces can also point to code that is not in the master branch anymore, so it's not like they are immune from it. In both cases (Java and Go), you can git-checkout the deployed commit and then locate the error. I…

Which proves that there is more load on the programmer to ensure that no two error messages are the same. What is this, are we back to programming in C with __LINE__ macros?

Re: Gopher Wrangling: Effective error handling in Go

#265

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?

A descriptive error message beats any stack trace. A stack trace does not actually tell you anything that's particularly interesting, there is a ton of irrelevant information and it's generally missing the values bound to the arguments and variables.

You can add context to a stack trace. So it's strictly a super set. And seeing the code path taken to the error is anything but irrelevant.

Re: Gopher Wrangling: Effective error handling in Go

#266

Earlier quoted context omitted.

You will only have problems with the same error message if they are in the same function, otherwise the wrapped errors will show a different path. It is possible, but they will be close to each other. Stack traces can also point to code that is not in the master branch anymore, so it's not like they are immune from it. In both cases (Java and Go), you can git-checkout the deployed commit and then locate the error. I…

Which proves that there is more load on the programmer to ensure that no two error messages are the same. What is this, are we back to programming in C with __LINE__ macros?

I believe the issue you're concerned about is relatively insignificant compared to your perception of its magnitude. But if this is something you are very concerned about, there are many approaches you can adopt in a Go codebase to make errors richer, such as using the "errors" package and a structure logger, which are enforceable at CI time and will give you stack traces.

Re: Gopher Wrangling: Effective error handling in Go

#267
post #49

Earlier quoted context omitted.

The problem with exceptions is that they can come from any line of code and cause a "return". Rust's question mark solves the issue because it marks which lines of code can cause a "return". Therefore, you can always see see the control flow of a function. Moreover, you can go even further if you really really really want a single control flow. You can write a clippy lint to disallow early returns (ban "return" keywo…

? enables chaining, chaining subverts comprehensibility in exactly the ways i'm describing

All languages have chaining: that's what `;` is for. Chaining together transitions in an imperative state machine isn't simpler than chaining together `Result`s, you're just used to it.

Re: Gopher Wrangling: Effective error handling in Go

#268
post #203

Earlier quoted context omitted.

It is easier to know that lowercase is package-specific, uppercase is exported, than knowing which field is private/public by default. Go reserved keywords: break, default, func, interface, select, case, defer, go, map, struct, chan, else, goto, package, switch, const, fallthrough, if, range, type, continue, for, import, return, var Java reserved keywords: abstract, continue, for, new, switch, assert, default, goto*,…

This is why you can do const true = false in golang The number of reserved keywords is not a bad thing. For example, I constantly missed `final` when I worked in golang. Just because a keyword doesn't exist does not make its usecase disappear. Same with other features like `enum` (extremely useful) and visibility rules. golang only has package private and public, not nearly as granular as one needs in practice, not t…

> The number of reserved keywords is not a bad thing.

I'm not saying reserved keywords are bad. I'm saying there's much more to learn about Java to learn programming, Go is limited with its' keywords and 'features', which often results in more LoC, but makes it super easy to get going, run into general programming problems like using a variable instead of a reference to it, etc.

In Java, you spend much more time learning the features of the language itself, even simple things like (s)Strings are not easy to understand, then add classes, inheritance, UTF-16, adding other libraries, build tools, JUnit and many, many other things that are given to you with Go.

Re: Gopher Wrangling: Effective error handling in Go

#269

Earlier quoted context omitted.

> Over 10k lines of code it becomes really hard to keep things straight. However, that's more due to its very limited scoping abilities. Could you please elaborate more on this?

With the default toolchain, Go has essentially two levels of visibility scoping: package-private (lower case) vs. exported (upper case) items, and module-internal vs. public packages (packages in the "internal" folder are not accessible from other modules). To make matters worse, all files in the same folder belong to the same package. (There are other toolchains out there that do things differently.) In larger proje…

Thank you for the in-depth response! Just to clarify my understanding, do you mean you want to encapsulate data structures within the same package (i.e. files in the same directory)? If so, I'm not clear why you can't break those up into a different package.

Re: Gopher Wrangling: Effective error handling in Go

#270
post #268

Earlier quoted context omitted.

This is why you can do const true = false in golang The number of reserved keywords is not a bad thing. For example, I constantly missed `final` when I worked in golang. Just because a keyword doesn't exist does not make its usecase disappear. Same with other features like `enum` (extremely useful) and visibility rules. golang only has package private and public, not nearly as granular as one needs in practice, not t…

> The number of reserved keywords is not a bad thing. I'm not saying reserved keywords are bad. I'm saying there's much more to learn about Java to learn programming, Go is limited with its' keywords and 'features', which often results in more LoC, but makes it super easy to get going, run into general programming problems like using a variable instead of a reference to it, etc. In Java, you spend much more time lear…

When I had to learn golang, picking up the syntax was easy, but it has many gotchas that you end up having to spend time to learn them anyway, which don't exist in Java (e.g. the Java compiler requires final or effectively final vars to be passed into lambdas, golang happily complies ending up with race conditions).

I don't see why learning language features is an issue. The language offers features to provide more correct and more expressive code.

golang does not solve the variable vs reference issue at all by the way, and in fact, introduces weird edge cases, such as nil interface not being equal to nil.

Why do you say Strings not easy to understand?

Post reply on HN