Thread-stream failures, shared by the async and sync clients.
Build the error for a protocol {"type": "error"} envelope.
Return the error in an unsolicited {"type": "error", "id": null} frame.
The server sends one just before it closes a thread stream whose read failed.
Whether reopening the stream would fail the same way.
True for a 4xx other than 408 and 429: the status of a refused stream request or WebSocket upgrade, or a WebSocket close code of 4000 plus that status. A server that rejects a WebSocket after accepting it closes with such a code, because a browser can't read the status of a refused upgrade.