Earlier quoted context omitted.
Having written maybe two lines of Go, many years ago, I guess I'm surprised that all of these cases make it past the type system. Like shouldn't it bitch if you try to return nil when it's expecting a non-nil value or an error? I guess I'll go try to find an online go thinger to find out.
There’s no way to tell Go that a value shouldn’t be nil.
Eris – A better way to handle, trace, and log errors in Go
41–50 of 61 posts
Re: Eris – A better way to handle, trace, and log errors in Go
#42Have spent a while in the py/js world but have switched to rust/go for part of this year -- biggest change is boilerplate relating to error handling. Automatic stack capture for exceptions is something my language could conceivably do on my behalf. Writing even 3 lines of code per function to propogate up the error is a huge pain, especially because it pollutes the return type -- MustWhatever() in go is much easier t…
Re: Eris – A better way to handle, trace, and log errors in Go
#43Earlier quoted context omitted.
What surprises me as a primarily JVM developer now supporting Go apps and dabbling in Go development is that the logging libraries (like klog) I've encountered don't support the level of configuration I'm used to in JVM apps. I miss being able to configure individual loggers at desired levels with a logback.xml in the JAR, but especially the ability to change logging levels at runtime. I guess it's part of the Go phi…
You might wanna look at using something like zap instead, as it enables you to do runtime loglevel changes...
Re: Eris – A better way to handle, trace, and log errors in Go
#44Earlier quoted context omitted.
Rust has a postfix `?` operator to propagate errors up the call stack.
as I understand it, this requires an Option or Result return type that matches the type of the statement The ? operator is better than nothing, but I still need my error types to match all the way up the stack
Re: Eris – A better way to handle, trace, and log errors in Go
#45Re: Eris – A better way to handle, trace, and log errors in Go
#46Earlier quoted context omitted.
Of course you can. Sad path first means, after you write your data types and interface signatures, writing the first stub implementations as func (t *Thing) Process(id int) (string, error) { return "", fmt.Errorf("not implemented") } and then filling them in gradually like func (t *Thing) Process(id int) (string, error) { dat, err := t.store.Read(id) if err != nil { return "", fmt.Errorf("error reading ID: %w", err)…
Sure, but in a better language, the second version already does the exact same thing as the first one. Your `return fmt.Errorf` is not exception handling, it is simply manual exception bubbling. It is boilerplate that you can forget to add, and that makes it harder to understand what the code is supposed to do. Maybe for the first error you are adding some context that the Read function didn't have, but for the secon…
Re: Eris – A better way to handle, trace, and log errors in Go
#47Earlier quoted context omitted.
I don’t buy the “huge pain” argument. I write lots of Python and Go, and the error boilerplate is a non-issue. I also appreciate that it’s explicit instead of implicit.
It's not just a pain to write. I've accidentally introduced way more bugs through Go style error handling than through Python style error handling. Some examples: Forgetting that a function returns an error: ... foo() // foo returns an error that isn't being handled. ... Forgetting to check the error returned by a function. Note a linter won't pick this up since the err variable is used later. ... err := foo() err =…
Re: Eris – A better way to handle, trace, and log errors in Go
#48Earlier quoted context omitted.
There’s no way to tell Go that a value shouldn’t be nil.
That's not exactly true. All struct types in Go can not be nil. However, they also can't be abstracted over in any way, so they are a poor idea for an error type - you want an error interface, and all interface types in Go indeed are nil-able.
Re: Eris – A better way to handle, trace, and log errors in Go
#49Earlier quoted context omitted.
Thanks for the info! And... Woah. That's kind of horrifying to me (though I totally get the explicitness of it)... does this just mean liberal amounts of: thing != nil everywhere? Or is the rest of the memory management I guess, uhh.., good/magical enough you don't have to worry about it constantly in calls further down the stack if you've checked it once? Or are you always feeding the nil check beast?
> does this just mean liberal amounts of: thing != nil everywhere Yes, it does. Whenever you call a function that can possibly fail, you are supposed to add: if err != nil { return err } You can think of it as unwinding the stack by hand. That's why a lot of people complain about Go error handling so much. That and a lack of generics. Looking at some code I've written, about 15-20% of the lines in a file are responsi…
I don’t think that’s what the parent meant by his question. He was asking if you have to add runtime checks all over to make sure any reference type isn’t nil; no, you don’t—you only add the checks for those for which nil is a valid state in the program (such as errors). If it’s an invalid state, it will panic because it’s an exceptional circumstance—a programmer error. This isn’t a defense of nil; only a clarification about how nil is dealt with. With this context, the rest of his question (the part you didn’t understand) becomes clearer.
Re: Eris – A better way to handle, trace, and log errors in Go
#50Earlier quoted context omitted.
as I understand it, this requires an Option or Result return type that matches the type of the statement The ? operator is better than nothing, but I still need my error types to match all the way up the stack
You can use the Error trait [1] from the stdlib, implement it for your error types and then just use the trait in your Result. That way you don't need the types to match and you can convert between then as needed while adding the previous errors to the chain. 1. https://doc.rust-lang.org/std/error/trait.Error.html