4 ms·
Do you write primarily HTTP / RPC services? I've found Go's error handling very tedious when "return an error to the caller" is almost always the answer, but fo
by closeparen 4y ago
Do you write primarily HTTP / RPC services? I've found Go's error handling very tedious when "return an error to the caller" is almost always the answer, but for background stuff, daemons, etc. it's nice.
- bilinguliar 4y agoI write HTTP/RPC and some TCP servers, implementing specs to parse files and data processing pipelines based on PubSub, NATs, etc. Whenever the server fails to do what is needed - in most cases, it will retry with a backoff. In case it is not retryable - most often, it will exit, an alert will fire, and I will start handling an incident. Background jobs run in a goroutine and send a non-retryable error to the channel. go func() { errChan <- s.ProcessData(ctx) }() Followed by a blocking select: select { case err := <- errChan: log.Printf(“Server failed: %s”, err) case <- ctx.Done(): log.Println(“Shutting down”) } Something along these lines.
- closeparen 4y ago>Whenever the server fails to do what is needed - in most cases, it will retry with a backoff. In case it is not retryable - most often, it will exit, an alert will fire, and I will start handling an incident. I don't follow. Requests have deadlines, so you can't keep trying forever. Often a persistent failure means the request itself is bad. Either invalid, or exposing an edge case that the system can't currently handle. These kinds of errors are always present at background levels in a high-scalability system; we have SLAs like 99.99% success rate to decide when there's really an incident. Crashing the entire server process because of one failed request sounds crazy.
- bilinguliar 4y agoMy bad. I misread your comment. Please see the response one level up.
- bilinguliar 4y agoI have misread your comment. So, your experience with handling errors that must be returned to the caller is tedious. Hmm, I do not feel it is tedious. I will likely bubble it up the stack, report it and return a relevant code. I appreciate that this is almost linear, without mental complexity of exception, where you occupy another part of your brain with accounting for exception handling.
- jen20 4y ago> report it and return a relevant code. This would be more convincing if the signature of func main in go even permitted an exit code. Instead one must use os.Exit which does not run defers, or have main consist primarily of a call to os.Exit(realMain()).