You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow customize how HTTP errors are rendered when websocket.Accept fails to upgrade #545
IDEA: Might be as simple as a new HttpErrorRenderer (or OnError, etc.) option added to websocket.AcceptOptions. When unspecified, default to a fn that implements current rendering behavior. It would take at minimum a ctx, the err and the http status code.
Nice addition: the full set of errors.New("..") would be exposed to user so that one can use errors.Is to get more granularity than provided http statuses.
We need this feature in order to produce https://www.rfc-editor.org/rfc/rfc9457.html (a standardized JSON error response format) when an error occurs in order to match the rest of our API which produces this error response format for all of its endpoints. Current hard-coded behavior prevents us to comply with our policy when WS upgrade fails in this library. Our user thus can't systematically assume this nice JSON format and must workaround this limitation...
Hey @jraygauthier. This is a good idea, and a shortcoming I've identified before. Could you expand upon on why the error handler needs to take ctx? Is it for values or for cancellation, and if the latter, what type of long-running operations do you expect it will be used to run?
Could you expand upon on why the error handler needs to take ctx? Is it for values or for cancellation, and if the latter, what type of long-running operations do you expect it will be used to run?
Hi @mafredri. My concern was more about proper cancellation in the context of graceful shutdown. I guess that as Accept takes the request (websocket.Accept(w, r, &websocket.AcceptOptions{})) that'd be the request's context so that when one cancels the request (most likely the BaseContext provided to one's http.Server), any long running operation one might want to run in that handler is bound to that request so that it remains possible to gracefully shutdown the server's websockets (which are just long lived requests).
If our error handler is provided with w, r just like Accept than we're already covered as the implementer can just r.Context() and get both extra values and cancellation from it.
Here's how I currently handle that graceful shutdown at the top level:
@jraygauthier thanks for the context. I’m still wondering why the context, or even r, need to be arguments? Could you provide real code examples where their inclusion add value compared to just w, err, statusCode? I would expect that typically the handler is just a plain write on w and there’s really no way to utilize a context then.
In very bespoke implementation, the caller could even capture a context and r via closure at the accept call-site, if needed.
In very bespoke implementation, the caller could even capture a context and r via closure at the accept call-site, if needed.
I agree there, in almost all cases w, err, statusCode would be plenty enough and as you say, taking those extra inputs via closure would be perfectly fine.
Could you provide real code examples
No actual code examples to provide here. Here are a couple of edge cases I can think of.
The context might be useful:
when using 3rd party lib that requires it
to extract values injected via middle-wares (my specific case where I have a developer mode which when active let me respond with extra detailed error information that would normally be only logged)
The request might be useful:
for responses whose content depends on headers
But as you said, those can anyway be captured via closure thus covering those less common edge cases.
Activity
mafredri commentedon Dec 16, 2025
Hey @jraygauthier. This is a good idea, and a shortcoming I've identified before. Could you expand upon on why the error handler needs to take
ctx? Is it for values or for cancellation, and if the latter, what type of long-running operations do you expect it will be used to run?jraygauthier commentedon Dec 16, 2025
Hi @mafredri. My concern was more about proper cancellation in the context of graceful shutdown. I guess that as
Accepttakes the request (websocket.Accept(w, r, &websocket.AcceptOptions{})) that'd be the request's context so that when one cancels the request (most likely theBaseContextprovided to one'shttp.Server), any long running operation one might want to run in that handler is bound to that request so that it remains possible to gracefully shutdown the server's websockets (which are just long lived requests).If our error handler is provided with
w, rjust likeAcceptthan we're already covered as the implementer can justr.Context()and get both extra values and cancellation from it.Here's how I currently handle that graceful shutdown at the top level:
mafredri commentedon Dec 17, 2025
@jraygauthier thanks for the context. I’m still wondering why the context, or even
r, need to be arguments? Could you provide real code examples where their inclusion add value compared to justw, err, statusCode? I would expect that typically the handler is just a plain write onwand there’s really no way to utilize a context then.In very bespoke implementation, the caller could even capture a context and
rvia closure at the accept call-site, if needed.jraygauthier commentedon Dec 18, 2025
@mafredri :
I agree there, in almost all cases
w, err, statusCodewould be plenty enough and as you say, taking those extra inputs via closure would be perfectly fine.No actual code examples to provide here. Here are a couple of edge cases I can think of.
The context might be useful:
The request might be useful:
But as you said, those can anyway be captured via closure thus covering those less common edge cases.