Live data from Hacker News

Gopher Wrangling: Effective error handling in Go

stephenn.com

181–190 of 310 posts

Re: Gopher Wrangling: Effective error handling in Go

#181
post #165
post #136

Earlier quoted context omitted.

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

Java is absolutely not a complex language. The “enterprise java” style is an unfortunate one that can actually be traced back to C++, but it is not a necessity at all, and due to the sheer size of the java ecosystem you will find plenty of examples of a more barebones approach — also supported by the language developers. I fail to see why I would go with go over java, besides.. perhaps some CLI app? With Graal even t…

>The “enterprise java” style is an unfortunate one >but it is not a necessity at all

The thing is in real life you have to deal with this kind of code most of the time. Because most of the time you deal with the old code or people who are used to some patterns you have to use too because you are part of the team.

Go enforces (kind of) a more barebones approach by default.

PS: I think it's poinless to compare two languages. We should rather compare real practices and read examples.

Re: Gopher Wrangling: Effective error handling in Go

#182
post #116

Go's error handling is a horrible mess: 1. It's easy to ignore returned errors without any compiler warnings. You have to rely on third party tools such as golangci-lint to report missing error handling. 2. Errors don't carry stack traces with them, you have to rely on third party libraries or custom errors to get that functionality and you will only get it for your own code, not in other libraries you are using. 3.…

One of the main reasons I created V.

It's pretty much Go with Option/Result that forces you to handle errors:

f := os.create('foo.txt') or { println(err) return }

https://vlang.io/compare#go

Re: Gopher Wrangling: Effective error handling in Go

#183
I differ with the author here, I prefer to log errors as soon as they come into "my" code (e.g. from external library or network call, etc.).

This is a good rule for any language, because you always ensure an error is logged once. In Go, you can add additional info from the caller to the Context to log higher level info, e.g. a trace span Id.

Re: Gopher Wrangling: Effective error handling in Go

#184
post #116

Go's error handling is a horrible mess: 1. It's easy to ignore returned errors without any compiler warnings. You have to rely on third party tools such as golangci-lint to report missing error handling. 2. Errors don't carry stack traces with them, you have to rely on third party libraries or custom errors to get that functionality and you will only get it for your own code, not in other libraries you are using. 3.…

The error handling is second nature to anyone who has done C or Unix programming. It just feels dirty not to check for an an error. This is one part I like about Go.

Which rules out the majority of people who learnt to code in the last 25 years (many unis have taught java since 2000ish)

Re: Gopher Wrangling: Effective error handling in Go

#185
post #164
post #154

Earlier quoted context omitted.

I agree that go and rust have different areas, but that was less clear when they were getting started. Back then go was trying to figure out what it meant by 'systems programming language' and rust had a similar threading model. Another point is that they do share similarities, which might we might now just describe as being 'modern': They're generally procedual -- you organize your code into modules (not classes) wi…

> I agree that go and rust have different areas, but that was less clear when they were getting started That I agree with. But Go is anything but modern on a language front. It shares almost nothing with Rust, which actually has a modern type system (from ML/Haskell). Even if we disagree about exceptions (I do like them as they do the correct thing most of the time, while they don’t mask errors, but include a proper…

I'm not arguying that go has modern tech, but rather that it has modern sensibilities. This means not trying to force 90s style OOP, preferring static linking for easier deployment, including a build system and package manager with the compiler and preferring static types with type inference to dynamic types.

This differentiates go, rust, zig, odin etc., from languages like C++, Java, C#, Python etc. I think it makes sense to describe that difference as one of modern sensibilities.

Re: Gopher Wrangling: Effective error handling in Go

#186
post #154

Earlier quoted context omitted.

I agree that go and rust have different areas, but that was less clear when they were getting started. Back then go was trying to figure out what it meant by 'systems programming language' and rust had a similar threading model. Another point is that they do share similarities, which might we might now just describe as being 'modern': They're generally procedual -- you organize your code into modules (not classes) wi…

> I really dislike exceptions because there's no documentation for how a function can fail. For this reason I prefer go style errors, which are an improvement on the C error story. Yes it has warts, but it's 80% good enough. I’m not a go developer. How does go document how a function can fail? A Java developer can use checked exceptions so that some information is in the signature. For unchecked exceptions the docume…

> I’m not a go developer. How does go document how a function can fail?

There's no magic to it. Errors are values, so it's a part of the function signature that there's an error code to check. In C++ any function can throw an exception and there's no way of knowing that it wont.

It's true that go doesn't document what _kinds_ of errors it can throw, but at least I know there's something to check.

Re: Gopher Wrangling: Effective error handling in Go

#188
post #144

Earlier quoted context omitted.

>3. It's unclear who should add context to error messages is it the caller or callee? Usually it gets skipped, leading to useless error messages Why is that unclear? Let's say you are writting a db client package and a service around it. The package's db.Exec(query) method should return and error that will have an error text received from db if any AND\OR context from the package itself. Then in your service you add…

>>3 > Why is that unclear? The usual advice is to follow what the stdlib does. Let's look at an example. Let's say we close a file and then try to set a deadline on it: f, _ := os.Create("/tmp/filename") f.Close() fmt.Printf("%v", f.SetDeadline(time.Now())) // output: use of closed file Okay, so in this case, it's the caller's responsibility to keep track of the filename and add the context of what file was already c…

> The usual advice is to follow what the stdlib does.

This seems to be a significant problem in general, because gophers want clear direction (after all the language was created specifically for… choices to be limited) so they take quips as gospels, but robpike, rsc, etc… take them more as suggestions / guidance (90/10, possibly even 80/20) to be moderated by taste.

I don’t remember which one but I think it was robpike who expressed frustration on one of the recently popular issues / proposals, because the proposal was essentially to legislate one of the more common quips, and they like being able to break those when useful or convenient.

I think there was also something similar to your exploration here with zero values, where despite the quip that you should “make the zero value meaningful” multiple standard library modules will straight up panic if fed zero values (a classic example being the File struct, `File.Name()` panics and pretty much every other method returns ErrInvalid, so a zero-valued File is useless, actively problematic, and the source of unnecessary overheads).

An other fun one is that you can’t call IsZero on a zero `reflect.Value`, and the error message is quite amazing:

    panic: call of reflect.Value.IsZero on zero Value
You need to carefully read the doc and notice that th middle paragraph documenting Value itself says:

> The zero Value represents no value. Its IsValid method returns false, its Kind method returns invalid, its String method returns “”, and all other methods panic.

Re: Gopher Wrangling: Effective error handling in Go

#189
post #181
post #165

Earlier quoted context omitted.

Java is absolutely not a complex language. The “enterprise java” style is an unfortunate one that can actually be traced back to C++, but it is not a necessity at all, and due to the sheer size of the java ecosystem you will find plenty of examples of a more barebones approach — also supported by the language developers. I fail to see why I would go with go over java, besides.. perhaps some CLI app? With Graal even t…

>The “enterprise java” style is an unfortunate one >but it is not a necessity at all The thing is in real life you have to deal with this kind of code most of the time. Because most of the time you deal with the old code or people who are used to some patterns you have to use too because you are part of the team. Go enforces (kind of) a more barebones approach by default. PS: I think it's poinless to compare two lang…

Ad absurdum than a new language will always be better, because usage patterns change and the new language doesn’t yet have any existing code bases using the old ones.

Re: Gopher Wrangling: Effective error handling in Go

#190
> Usually this isn’t necessary and its better to just return the error unwrapped.

This is a terrible advice. Wrapping is extremely helpful in providing additional context for the error travelling up the call stack. Without wrapping, one typically ends up with software logging generic errors like "file not found" , which you can't act on because... you don't know where it's coming from. If you skip error wrapping, better be ready to enjoy quality time when production crashes.

Post reply on HN