servant-websockets icon indicating copy to clipboard operation
servant-websockets copied to clipboard

Successful connections are logged as 500 errors

Open Alex0jk opened this issue 3 years ago • 3 comments

Hey, I have been using this library and noticed some inconvenient behavior when adding logging. When adding a logging middleware (any logging middleware should work), and then requesting a connection to the WebSocket, the logs will show a 500 error. The connection is successful, and no other issues seem to exist. I suspect there should an exception being raised somewhere but I am not really sure where. To test this I used the example provided in the documentation in this library with a basic logger:

import Network.Wai
import Network.Wai.Handler.Warp
import Servant
import Network.WebSockets.Connection (PendingConnection, sendTextData, forkPingThread, acceptRequest)
import Servant.API.WebSocket (WebSocketPending)
import Control.Monad.IO.Class
import Control.Monad
import Data.ByteString.Char8
import Control.Concurrent
import Network.Wai.Middleware.RequestLogger

startApp :: IO ()
startApp = run 8080 app

app :: Application
app = logStdout $ serve api server

api :: Proxy WebSocketApi
api = Proxy

type WebSocketApi = "stream" :> WebSocketPending

server :: Server WebSocketApi
server = streamData
 where
  streamData :: MonadIO m => PendingConnection -> m ()
  streamData pc = do
     c <- liftIO $ acceptRequest pc
     liftIO $ forkPingThread c 10
     liftIO . forM_ [1..] $ \i ->
       sendTextData c (pack $ show (i :: Int)) >> threadDelay 1000000

When connecting to the websocket, the log will show something like this: 127.0.0.1 - - [07/Feb/2022:09:05:21 -0500] "GET /stream HTTP/1.1" 500 - "" "" where 500 - "" is the response and it represents a HTTP 500 error.

Any help figuring this out is appreciated.

Alex0jk avatar Feb 07 '22 14:02 Alex0jk

I face the same issue.

Swordlash avatar Feb 16 '22 13:02 Swordlash

@Alex0jk This is "upstream" issue, if I can say so. See https://hackage.haskell.org/package/wai-websockets-3.0.1.2/docs/src/Network-Wai-Handler-WebSockets.html#websocketsApp

We construct a ResponseRaw with a "backup" argument handling HTTP 500. According to the responseRaw docs, This function requires a backup response to be provided, for the case where the handler in question does not support such upgrading (e.g., CGI apps). So the second argument is only a "backup response", it is usually never sent anywhere. Unfortunately, wai's function responseStatus returns a backup's status code for ResponseRaw responses. That's why you see http 500 in logs - it's the backup's response code, not something that has been sent anywhere in the network.

I think we may close this issue and create an issue upstream - that a RequestLogger is unrelaible for raw responses.

Swordlash avatar Feb 18 '22 14:02 Swordlash

@Swordlash was there an issue upstream or did you create one?

flip111 avatar Mar 27 '24 21:03 flip111