Live data from Hacker News

Errors vs. exceptions in Go and C++ in 2020

dr-knz.net

31–40 of 73 posts

Re: Errors vs. exceptions in Go and C++ in 2020

#31
post #19
post #10

Earlier quoted context omitted.

>It's designed to force people to handle the damn error as near to the call as possible. But that is sometimes the wrong design. If you have functions A() --> call B() --> call C() ... and C() has an error because of a memory allocation failure or a network connection being down, sometimes the best context to handle that error is the outermost function A() and not C(). That's why some programmers don't like copypasti…

What if we designed a system where there are two kinds of failures that can be returned? One where the caller is forced to address it by the compiler, and one that is transparent to the caller, but can be caught and addressed by anyone in the call stack (probably the top level)? And one could convert one type of failure to the other. So if you call a library function and it returns the force-you-to-address kind of er…

I think everyone has had this distinction on their mind when designing error handling in the past thirty years or so, it’s just that figuring out an ergonomic way to express it is quite hard.

In some languages the distinction is between logic errors and runtime errors. In Java, checked and unchecked exceptions. In Go, err and panic. Rust also has Err() and panic!().

If you look at, say, the evolution of the “if” statement, it was a number of years before this “obvious” control structure was added to programming languages. So there might be something similarly obvious for error handling, we just haven’t figured it out yet.

Re: Errors vs. exceptions in Go and C++ in 2020

#32
post #10

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

>It's designed to force people to handle the damn error as near to the call as possible. But that is sometimes the wrong design. If you have functions A() --> call B() --> call C() ... and C() has an error because of a memory allocation failure or a network connection being down, sometimes the best context to handle that error is the outermost function A() and not C(). That's why some programmers don't like copypasti…

Well there is a language that lets you decide how to handle errors separately from the code that actually handles them (eg separating the code that says “please retry” from the code that retries). That language is Common Lisp. But error handling in it is still a pain.

The one advantage it has over most exception systems in my opinion is that the equivalent of try-finally is much more common than try-catch. With exceptions, code often does weird things because it isn’t expecting to lose control flow when an exception is raised, but most languages don’t make it easy to catch stack unwinding a and clean up. In Common Lisp unwind-protect plus the style of with-foo macros tends to make it more common for functions to work when control transfers out of them in abnormal ways.

Re: Errors vs. exceptions in Go and C++ in 2020

#33

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!".

Regardless of one's view of execution handling, why would anyone even bother to do this? If you don't catch it and exit the program will exit anyway.

Re: Errors vs. exceptions in Go and C++ in 2020

#34
post #6

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> that the actual performance cost for checking the error return is random, variable, and small. Good to know :) That is certainly not the article's conclusion. The cost is deterministic, constant and non-negligible.

> and non-negligible

This is probably a matter of discretion. Considering the overall performance of Go applications compared to other languages, 4 to 10% is quite low. The measurement error might also be a few percent.

Re: Errors vs. exceptions in Go and C++ in 2020

#35
post #12

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

Go's thing is more "encourage" to handle errors than "force", given that the compiler has nothing to say about unhandled errors in the presence of certain variable reuse patterns, or completely unassigned returns. https://play.golang.org/p/mu5fbUrV322

That’s the correct way to present it IMHO. With Go you’re encouraged to deal with the error directly (two choices: return it, or do something about it), so that when reading you can follow what is happening at any time. When reading a Go function you can always say for sure if an error occurs with a given call and how it is handled.

If for some reasons the project consider that checking errors should be enforced, that’s simple to do by using go-lint or other linters.

Re: Errors vs. exceptions in Go and C++ in 2020

#36
post #17

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> It's designed to force people to handle the damn error as near to the call as possible. If they wanted to "force people" they could use Optionals and really force them. This no more forcing than mandating checked exceptions -- the user can just return the err immediately, like in Java they can just add a throws and propagate for others to handle, or an empty try/catch and ignore it...

You have go-lint or other linters to enforce it. It’s a per-project choice.

Re: Errors vs. exceptions in Go and C++ in 2020

#37
post #33

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". Regardless of one's view of execution handling, why would anyone even bother to do this? If you don't catch it and exit the program will exit anyway.

To have cleaner logs maybe? Stack trace are often a mess to parse. Or at least correctly close resources such as DB connections before exiting?

Re: Errors vs. exceptions in Go and C++ in 2020

#38

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> It's designed to force people to handle the damn error as near to the call as possible. This is always the wrong way to handle errors. If a function returns an 'error' that needs be handled at the call site, then it isn't an error, it's a variant return type. Errors are things that can't be recovered from but must be handled to release resources. You want this to happen in some central place, not scattered ad-hoc i…

I think there is a misunderstanding. There isn’t just a single type of errors. Every time you get an error object in Go you ask yourself “should I do something about it or not”. If no then you add some context and return it to the parent, that’s a perfectly valid way to handle it. Otherwise you do your specific piece of logic to recreate your ressources or whatever is needed.

Not all errors require the same treatment and there isn’t a single strategy to manage them.

Re: Errors vs. exceptions in Go and C++ in 2020

#39
post #17

I think they missed the point of Go's convention. It's designed to force people to handle the damn error as near to the call as possible. I've seen way too many programs with a single exception handler right at the base of the program, that just goes "whoops, something bad happened, bye!". I've even seen this anti-pattern used with Go's panic-recover mechanism. It's an interesting find though, that the actual perform…

> It's designed to force people to handle the damn error as near to the call as possible. If they wanted to "force people" they could use Optionals and really force them. This no more forcing than mandating checked exceptions -- the user can just return the err immediately, like in Java they can just add a throws and propagate for others to handle, or an empty try/catch and ignore it...

IMO, Optionals or Either are superior to returning a pair (value, error) because they cannot return both a value and an error, thus removing one possible cause of bugs (likely a fairly small one! As it doesn’t prevent a function from constructing both a result and an error and only returning the error), but I don’t see how optionals force handling errors more than returning a pair (value, error).

Surely, you can just check whether the optional has a value, use it when it is available, and ignore the other case.

Re: Errors vs. exceptions in Go and C++ in 2020

#40
post #10

Earlier quoted context omitted.

>It's designed to force people to handle the damn error as near to the call as possible. But that is sometimes the wrong design. If you have functions A() --> call B() --> call C() ... and C() has an error because of a memory allocation failure or a network connection being down, sometimes the best context to handle that error is the outermost function A() and not C(). That's why some programmers don't like copypasti…

Well yeah, but that's a situation that C() cannot predict; it's an unexpected error. 99% of Go's errors are expected errors that can and should be handled - you mention a network connection being down, that's an expected outcome when doing anything related to a network. A memory allocation failure is unexpected, and more down to the OS than the application itself; that's where a panic is in order and a last moment "s…

This is all true. But there are static checkers to find these issues, it's not a huge deal. Having the power to ignore the convention when I want to is good :)
Post reply on HN