Uh, wait a second… not only is the error not shown in the log, the request also has a HTTP status code of 200. Maybe those two issues are related? Like this: Caddy for some reason doesn’t know that there was a PHP error, so it doesn’t print to the error log.
On a hunch, I dug into this a bit. Looks like a bit of code from v1 never made it to v2.
The code would grab the stderr output from the fastcgi connection and wrap it up in a LogError type and pass it up to the caller.
In v2, we don’t do things the same way, because fastcgi is now no longer its own HTTP handler, but a transport under reverse_proxy (the Caddyfile kinda hides that away, but check the adapted JSON config if you want proof, or see the php_fastcgi docs, the Expanded Form section). We can’t just send up an error to reverse_proxy directly because then it would trigger other behaviour making the response look like a 502 Bad Gateway which is untrue.
Anyways, the fastcgi transport in Caddy v2 is missing that wiring to make it possible to display these errors from PHP at all. So we have some work to do there.
But I’m unsure the best way to go about it, we’ll have to have some discussion. For example do we want it to be an opt-in thing to show the errors, there’s pros and cons to that, it could be a “breaking change” or introduce “data leaks” if the error logs contain sensitive information, etc, but the typical user expectation might be that they are logged by default.
FWIW, I replicated it locally (on Linux, not Windows) and I do get status 500 from a simple throw new Exception script, not a 200.
The relevant bit of code from v1 (for my own sake, to follow up later):