No, you don't panic, you are most likely to corrupt your data and maybe continue working as if everything was fine. If you are lucky, your code panics.
> ... you already know where to start debugging.
Grep all occurrences of "_"?
> That's much better than having an exception bubble up from deeeeep inside your code with some context-less cryptic message or number, isn't it?
No, the exception carries all the context you need. If you ignored a previous exception, the next one won't be as useful as it could, but at least your code breaks loudly.
There's no way to know whether the programmer actually considered all the error cases (they are generally very poorly documented in Go code), and there's no way to know if the called function added errors at some later date. If it's though an interface, there's no way to know that all implementations have the same errors.
It's really an 80s-era approach to error handling, and that's bad.
I don't see how that follows. A stack trace (as initially cryptic as it seems) is a record of all the code that would have affected the current buggy state you find yourself in. If anything, a stack trace isn't comprehensive enough, ideally it would include all known/named values at every level of the stack... a large quantity of information, to be sure, but perhaps it could be narrowed down by diffing each stack level with the previous one or something. But if you could have those 2 things, you would have literally ALL the information you needed to fix the bug. Since bugs are programmer-unexpected states, and the stack trace plus the known values at each stack level are LITERALLY the entire state.
So correct me if I'm wrong, if you don't assign an error to a variable on the same line in Go, it throws? Because it was my understanding that there were absolutely no throws at all in Go. Or is it only that certain kinds of statements are expected to possibly error, and must therefore be assigned to a variable (or _)?
Assigning to _ effectively ignores the error, but is considered a very bad practice.
Unavoidable runtime errors (eg divide by 0) will generate a panic, which is similar to an exception, but is uncatchable within the Go routine it originates in.
Nonsense.
fmt.Println("Hello world!")
I just ignored an error and it compiles fine. Go check the return type of Println:https://golang.org/pkg/fmt/#Println
tl;dr, it's very easy to accidentally ignore errors in functions that are side-effecting or modify parameters. Been there, done that.
(gdb) bt full"Syntax error, expected token HTTP_METHOD but got 'B'"
In Go, with proper error handling I'd get a message like:
"Couldn't do flubber transfer: Unable to negotiate protocol: Sent supported protocols but remote responded with HTTP 400 "Bad Request": Missing required field 'version' in protocol definition"
As "error" is an interface, this message is only the tip of the iceberg: the error object itself may contain the address of the remote server, the protocol definitions that were sent, the response body that we got and any other relevant contextual payload.
This is all due to the error being treated in-context as opposed to just bubbling up.
Well yeah, if you handle errors properly, you get better results than if you don't.
The point is that with exceptions, it fails loudly and you get the cryptic message even if you forget, whereas with Go, if you forget to handle an error, you just get weird behaviour and corrupt data.
And if you want more helpful error messages, you can catch the exceptions and report the context just as easily as you can in Go.
> I don't see how that follows. A stack trace (as initially cryptic as it seems) is a record of all the code that would have affected the current buggy state you find yourself in.
You get stack traces in Java, C#, Python, etc. You don't get them in C++ (well, you aren't guaranteed to get them).