3 ms·
Thank you for taking the time to reply so thoughtfully! So, if I'm understanding you correctly: An exception is an unexpected failure at runtime that could ha
by shepherdjerred 2y ago
Thank you for taking the time to reply so thoughtfully!
So, if I'm understanding you correctly:
An exception is an unexpected failure at runtime that could have been caught by the programmer. For example, you might have a switch block with a default block saying "this can never happen". The programmer might miss a case in the switch block leading to an exception. This would be analogous to an unchecked exception (RuntimeException) in Java -- these exceptions are not required to be caught.
In Go, `panic` creates an instance of the type `exception`. When `panic` is executed it attaches metadata like the stack trace to the created exception. When I say "exception" this is the behavior that most people think about.
An error is for an expected failure, like a file potentially not existing when performing I/O operations. Like you said (and this matches my understanding), error types are just a normal type -- really any type that implements the `Error` interface. There are a lot of utilities functions/libraries that act on that `Error` interface, like assertions for unit tests, the multierr library, etc.
`Error` is similar to a checked exception (Exception) in Java, though it misses the behavior you expect like requiring it to be caught, and the try-catch syntax. Additionally, you don't have the stack trace/metadata automatically added.
Go programmers seem to _heavily_ prefer errors over exceptions, even when they should be using `panic`.
My problem with errors in Go are that they are too easy to ignore accidentally and they don't contain stack traces, so they can be hard to track down. I inherited a codebase where we had _hundreds_ of unchecked errors being silently ignored.
I understand that these problems go away if you have linters or a very detail-oriented team, but I unfortunately have no power over the actions of my team before I join. It's also _very_ hard to convince a team that they've been doing things incorrectly by ignoring errors.
- randomdata 2y ago> My problem with errors in Go are that they are too easy to ignore accidentally This is a problem for values of all types, not just errors. One I'm not sure we've figured out how to solve[1]. There are a few languages out there that force variable assignment to try and address the problem, but even then there is really nothing to say that you haven't accidentally ignored the variable assigned. > It's also _very_ hard to convince a team that they've been doing things incorrectly by ignoring errors. To be fair, if you are able to completely leave out entire blocks of logic without anyone noticing even under the most cursory of testing, perhaps it wasn't actually needed? Forgetting entire code branches isn't exactly a subtle bug. [1] Short of going all the way to formal proofs.
- hot_gril 2y agoIt's a problem for values of all types, which is why exceptions are usually handled specially in other languages. I get that it seems impure, but everything you call has some way to fail <1% of the time that you probably want to handle very differently from any other outcome. It's sensible for a language to force you to either designate a different code path for that or let it bubble up (edit: which, to clarify, Golang does not enforce with error return types, which is what the other person dislikes about it).
- randomdata 2y agoI've read a lot of code in my life. I see that exception handlers are sometimes used to carry errors, virtually always exceptions, but almost never anything else. Who is it that you are think are passing around email addresses and geocooreinates using exception handlers? But even assuming it is done sometimes, is the developer going to actually handle it? I don't know how many times I've come across "catch" blocks that are empty or something equally inappropriate. Nothing was gained. It turns out that programmers will still forget no matter how hard you try to hold their hand. I'm not sure there is any other solution than to test it, and once you get into testing, entire blocks of logic missing are going to stick out like a sore thumb. Forgetting an entire branch is not exactly a subtle bug. At that point it really doesn't matter what language constructs you do or don't have available.
- shepherdjerred 2y ago> I don't know how many times I've come across "catch" blocks that are empty or something equally inappropriate. Nothing was gained. It turns out that programmers will still forget no matter how hard you try to hold their hand. You are right, but the difference is that the programmer is making the choice to ignore that error versus accidentally ignoring the error.
- randomdata 2y agoThere was no indication that it was an active choice. I'm speaking to where it was clearly incorrect behaviour, not where one honestly wanted to ignore the condition. I'm assuming these programmers would write out the boilerplate (perhaps even automatically by some IDE feature) and then forgot to return to it to fill in the logic. And fair enough. It would be just as easy to forget to do that as it would be to forget to handle errors in any other language. There is no silver bullet here.