I think that your question is the result of a mental model you maintain which is instilled by popular mainstream languages such as Java, C++, C#, PHP and zillions of other which simply got exceptions wrong.
The thing is, exceptions per se are not a wrong concept but abusing them to handle cases which are, in reality, not exceptional is. My personal pet peeve is the filesystem handling API of Java (and .NET, which copied that of Java almost verbatim): why on Earth failure to open a file results in an exception if that file does not exist? The filesystem is an inherently racy medium, and is specified to be racy, so the only correct way to ensure a file exists before opening it for reading is to just open it and then check for "file does not exist" error: the case of the file not existing is not exceptional at all.
Hence Go clearly separates exceptional cases from plain normal errors.
The motto of the stance Go maintains on handling errors is "Errors are values" and thus normal expected errors are handled as values, and panic()
serves to handle exceptional cases. A good simple example:
An attempt to dereference a nil
pointer results in a panic
.
The rationale: your code went on and tried to dereference a pointer which does not point to any value. The immediately following code clearly expects that value to be available—as the result of the dereferencing operation. Hence the control flow clearly can't proceed normally in any sensible way, and that's why this is an exceptional situation: in a correct program, dereferencing of nil
pointers cannot occur.
The remote end of a TCP stream abruptly closed its side of the stream and the next attempt to read from it resulted in an error.
That's pretty normal situation: one cannot sensbily expect a TCP session to be rock-solid: network outages, packet drops, unexpected power blackouts do occur, and we have to be prepared for unexpected stream closures by our remote peers.
A minor twist to panic()
is that Go does not force you to blindly follow certain dogmas, and you can freely "abuse" panic/recover in tightly-controlled specific cases such as breaking out from a deeply-nested processing loop by panic
king with an error value of a specific type known and checked for at the site performing recover
.
Further reading:
- "Why should I have written ZeroMQ in C, not C++".
- "Errors are values".
- "Is function parameter validation using errors a good pattern in Go?".