Go has been my daily driver for over a decade. I was in the past a C++ programmer. In what ways am I writing exception-safe code when I write ordinary Go code?
I've run into issues where panics cause half of what should be a multistep but assumed to be atomic transaction to occur, putting the system into a goofy state that required fairly manual intervention. In my case a system daemon that required someone to manually fix up system state on the CLI and restart the system.
That's like, strong-form exception safety, a problem in most mainstream languages. But when C++ people talk about "exception safety", they're talking about basic or weak-form exception safety: not leaving dangling pointers and resources as a result of unexpected control transfer. That style of defensiveness is not common in Go code.
Well that's the thing, I am talking about resources left 'open' since they didn't complete their lifecycle due to the unexpected control flow. Yes, it's not common in go code, but I think that's more a combo of the GC making dangling memory not a problem, and the environment that most go code lives in (ie. kubernetes clusters or some equivalent) where the other resources leaked are eventually reclaimed by the autoscaler and other devops automation.
The GC is ubiquitous, and definitely a point in favor for go for the vast majority of use cases, but I've found it more difficult than anticipated to write go code that manipulates resources other than memory that the environment you're running in won't clean up for you. And that's coming from C++ code originally including the exception safety issues.
> panic = very serious problem, what do you expect?
Even the Go standard library itself panics (and recovers) when you try to e.g. json-encode a NaN, which doesn't seem like something that should make the system unstable.
encoding/json largely moved away from using exceptions internally for errors, I believe due to performance reasons. Also you're making a strawman by equating one explicit intentional use of a specific panic with all panics everywhere.
This is a direct result of Go's lacking error handling, and would not be necessary if they'd have learned from C++ and Java's mistakes, instead of just repeating them.
That code is not exception safe. It may be a contrived example, but in code review I've many times seen real code that is not exception safe, for basically the same reason.
A held lock is fairly benign (only causes a deadlock, not corrupted data) if the net/http.Server swallows it in your handler, or fmt.Print swallows it. But some other errors are not as benign.