phoenixframework/phoenix — pull request #531 by fishcakez (2014-12-11 18:09:55+00:00)
Title: Improve websocket error to give accurate MFA

In #530 the top MFA in the reason would point to the `Endpoint`. However the `Endpoint` has returned and so the MFA is inaccurate. Therefore the websocket upgrade is made to look like a plug (even though it isn't!) and this allows us to get a nice + accurate MFA that can parsed by the Plug translator. I admit this is abit of hack but we want to keep the `Plug.Conn` information in the log message.

Note that a fix is required to support hibernation of websockets, as the stack is lost on hibernation and so an errors won't be caught by `Phoenix.Endpoint.CowboyHandler`.

Before:
```
[error] #PID<0.262.0> running ChannelExample.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /ws
** (exit) exited in: Phoenix.Transports.WebSocket.ws_handle("{\"channel\":\"gamechannel\",\"topic\":\"topic\",\"event\":\"join\",\"message\":{\"id\":123}}", %{router: ChannelExample.Router, serializer: Phoenix.Transports.JSONSerializer, sockets: #HashDict<[]>})
** (EXIT) an exception was raised:
** (RuntimeError) goo
(channel_example) web/channels/game_channel.ex:5: ChannelExample.GameChannel.join/3
(phoenix) lib/phoenix/channel/transport.ex:96: Phoenix.Channel.Transport.dispatch/4
(phoenix) lib/phoenix/channel/transport.ex:67: Phoenix.Channel.Transport.dispatch/4
(phoenix) lib/phoenix/transports/websocket.ex:45: Phoenix.Transports.WebSocket.ws_handle/2
(phoenix) lib/phoenix/router/cowboy_websocket.ex:63: Phoenix.Router.CowboyWebSocket.websocket_handle/3
(cowboy) src/cowboy_websocket.erl:588: :cowboy_websocket.handler_call/7
(phoenix) lib/phoenix/router/cowboy_websocket.ex:14: Phoenix.Router.CowboyWebSocket.resume/3
(phoenix) lib/phoenix/endpoint/cowboy_handler.ex:18: Phoenix.Endpoint.CowboyHandler.upgrade/4
```
After:
```
[error] #PID<0.262.0> running Phoenix.Endpoint.CowboyWebsocket terminated
Server: localhost:4000 (http)
Request: GET /ws
** (exit) exited in: Phoenix.Transports.WebSocket.ws_handle("{\"channel\":\"gamechannel\",\"topic\":\"topic\",\"event\":\"join\",\"message\":{\"id\":123}}", %{router: ChannelExample.Router, serializer: Phoenix.Transports.JSONSerializer, sockets: #HashDict<[]>})
** (EXIT) an exception was raised:
** (RuntimeError) goo
(channel_example) web/channels/game_channel.ex:5: ChannelExample.GameChannel.join/3
(phoenix) lib/phoenix/channel/transport.ex:96: Phoenix.Channel.Transport.dispatch/4
(phoenix) lib/phoenix/channel/transport.ex:67: Phoenix.Channel.Transport.dispatch/4
(phoenix) lib/phoenix/transports/websocket.ex:45: Phoenix.Transports.WebSocket.ws_handle/2
(phoenix) lib/phoenix/router/cowboy_websocket.ex:63: Phoenix.Router.CowboyWebSocket.websocket_handle/3
(cowboy) src/cowboy_websocket.erl:588: :cowboy_websocket.handler_call/7
(phoenix) lib/phoenix/router/cowboy_websocket.ex:14: Phoenix.Router.CowboyWebSocket.resume/3
(phoenix) lib/phoenix/endpoint/cowboy_handler.ex:18: Phoenix.Endpoint.CowboyHandler.upgrade/4
```