Updating README.md adding 'System-generated error responses' and 'Panic recovery in other goroutines' sections.
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 59s

This commit is contained in:
Maxime Delporte
2025-10-23 17:16:25 +02:00
parent 7057f89038
commit e30eac9c4d

View File

@@ -100,6 +100,40 @@ So, if we want to customize how something is encoded, all we need to do is imple
An example is available here : **internal/data/runtime.go** An example is available here : **internal/data/runtime.go**
### System-generated error responses
In certain scenarios Go's **http.Server** may still automatically generate and send plain-text HTTP responses. These scenarios include when :
- The HTTP request specifies an unsupported HTTP protocol version.
- The HTTP request contains a missing or invalid **Host** header, or multiple **Host** headers.
- The HTTP request contains an empty **Content-Length** header.
- The HTTP request contains an unsupported **Transfer-Encoding** header.
- The size of the HTTP request headers exceeds the server's **MaxHeaderBytes** setting.
- The client makes a HTTP request to an HTTPS server.
For example, if we try sending a request with an invalid **Host** header value, we will get a response like this:
`$ curl -i -H "Host: こんにちは" http://localhost:4000/v1/healthcheck
HTTP/1.1 400 Bad Request: malformed Host header
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request: malformed Host header`
Unfortunately, these responses are hard-coded into the Go Standard library, and there's nothing we can do to customize them to use JSON instead.
But while this is something to be aware of, it's not necessarily something to worry about. In a production environment it's relatively unlikely that well-behaved, non-malicious, clients would trigger these responses anyway, and we shouldn't be overly concerned if bad clients are sometimes set a plain-text response instead of JSON.
### Panic recovery in other goroutines
It's important to realize that our middleware will only recover panics that happen in the _same goroutine that executed the **recoverPanic()** middleware_.
If, for example, you have a handler which spins up another goroutine (e.g. to do some background processing), then any panics that happen in the background goroutine will not be recovered - not by the **recoverPanic()** middleware... and not by the panic recovery build into **http.Server**. These panics will cause your application to exit and bring down the server.
So, if you are spinning up additional goroutines from within your handlers and there is any chance of a panic, you **must make sure** that you recover any panics from within those goroutines too.
A demonstration will follow when we will use a background goroutine to send welcome emails to our API users.
### Performance ### 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. 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.