From 6d09a4f545d7eb47e2ef9f624cc8d1b45fd99b14 Mon Sep 17 00:00:00 2001 From: Maxime Delporte Date: Sat, 25 Oct 2025 09:52:57 +0200 Subject: [PATCH] Adding 'Panicking vs returning errors' section --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 19e1f8d..36d2b7c 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,20 @@ So, if you are spinning up additional goroutines from within your handlers and t A demonstration will follow when we will use a background goroutine to send welcome emails to our API users. +### Panicking vs returning errors + +The decision to panic in the **readJSON()** helper if we get a **json.InvalidUnmarshalError** error isn't taken lightly. It's generally considered best practice in Go to return your errors and handle them gracefully. + +But - _in some specific circumstances_ - it can be OK to panic. And you shouldn't be too dogmatic about _not panicking_ when it makes sense to. + +It's helpful here to distinguish between the two classes of error that your application might encounter. + +The first class of errors are _expected errors_ that may occur during normal operation. Some examples of expected errors are those caused by a database query timeout, a network resource being unavailable, or bad user input. These errors don't necessarily mean there is a problem with your program itself - in fact, they're often caused by things outside the control of your program. Almost all the time, it's good practice to return these kinds of errors and handle them gracefully. + +The other class of errors are _unexpected errors_.These are errors which should not happen during normal operation, and if they do it is probably the result of a developer mistake or a logical error in your codebase.These errors are truly exceptional, and using _panic_ in these circumstances is more widely accepted. In fact, the Go standard library frequently does this when you make a logical error or try to use the language features in an unintended way - such as when trying to access an out-of-bounds index in a slice, or trying to close an already closed channel. + +I'd recommend trying to return and gracefully handle unexpected errors in most cases. The exception to this is when _returning the error_ adds an unacceptable amount of error handling to the rest of your codebase. + ### Performance **json.MarshalIndent()** takes 65% longer to run and uses around 30% more memory than **json.Marshal()**, as well as making two more heap allocations. Those figures will change depending on what you're encoding, but they're fairly indicative of the performance impact.