question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Websocket timeout causes process to crash

See original GitHub issue

Describe the bug Following the documentation, I setup a basic hello world http and websocket server (code below). Running the code works fine but after some time of inactivity a TimeoutError is thrown which kills the entire process. This seems like unexpected behavior. Is that correct? Anyway to prevent/catch the TimeoutError?

To Reproduce Compile and run the code below. Send a hello message then walk away. After some time the following exception occurs killing the process:

$> tsc lib/server/http.ts      
$> node lib/server/http.js 
λ - 60355 - 2021-07-17 23:45:17 - websockets [Context] - Registered: "LoggerToken"
λ - 60355 - 2021-07-17 23:45:17 - http [Context] - Registered: "HttpServerClient"
λ - 60355 - 2021-07-17 23:45:17 - http [Context] - Registered: "HttpRequestBus"                                                                                                                       
λ - 60355 - 2021-07-17 23:45:17 - http [Context] - Registered: "LoggerToken"                                                                                                                          
λ - 60355 - 2021-07-17 23:45:17 - http [Context] - Registered: "HttpServerEventStream"                                                                                                                
λ - 60355 - 2021-07-17 23:45:17 - http [Context] - Registered: "WebSocketServer"                                                                                                                      
λ - 60355 - 2021-07-17 23:45:17 - http [Router] - Effect mapped: / GET                                                                                                                                
λ - 60355 - 2021-07-17 23:45:17 - http [Router] - Effect mapped: /(.*) *                                                                                                                              
λ - 60355 - 2021-07-17 23:45:17 - http [Server] - Server running @ http://127.0.0.1:8007/ 🚀                                                 
λ - 60355 - 2021-07-17 23:45:37 - websockets [Server] - Connected incoming client "c554d454-858c-4d4c-aadd-70f0fa7dee87" (::ffff:127.0.0.1)
New client connection
λ - 60355 - 2021-07-17 23:46:10 - websockets [EVENT_IN] - HELLO, id: c554d454-858c-4d4c-aadd-70f0fa7dee87
λ - 60355 - 2021-07-17 23:46:10 - websockets [EVENT_OUT] - HELLO, id: c554d454-858c-4d4c-aadd-70f0fa7dee87 and sent to "::ffff:127.0.0.1"
λ - 60355 - 2021-07-18 00:58:05 - websockets [Server] - Closed connection form client "c554d454-858c-4d4c-aadd-70f0fa7dee87" (::ffff:127.0.0.1)
λ - 60355 - 2021-07-18 00:58:05 - websockets [ServerListener] - OutgoingEvent stream completes
λ - 60355 - 2021-07-18 00:58:05 - websockets [ServerListener] - OutgoingEvent stream completes
λ - 60355 - 2021-07-18 00:58:05 - websockets [ServerListener] - OutgoingEvent stream completes

node_modules/rxjs/dist/cjs/internal/util/reportUnhandledError.js:13
            throw err;
            ^                                                                                      
Error
    at _super (node_modules/rxjs/dist/cjs/internal/util/createErrorClass.js:7:26)
    at new TimeoutErrorImpl (node_modules/rxjs/dist/cjs/internal/operators/timeout.js:14:9)
    at timeoutErrorFactory (node_modules/rxjs/dist/cjs/internal/operators/timeout.js:60:11)
    at AsyncAction.<anonymous> (node_modules/rxjs/dist/cjs/internal/operators/timeout.js:37:34)
    at AsyncAction.<anonymous> (node_modules/rxjs/dist/cjs/internal/util/caughtSchedule.js:8:21)
    at AsyncAction._execute node_modules/rxjs/dist/cjs/internal/scheduler/AsyncAction.js:76:18)
    at AsyncAction.execute (node_modules/rxjs/dist/cjs/internal/scheduler/AsyncAction.js:64:26)
    at AsyncScheduler.flush (node_modules/rxjs/dist/cjs/internal/scheduler/AsyncScheduler.js:39:33)
    at listOnTimeout (internal/timers.js:554:17)                                                   
    at processTimers (internal/timers.js:497:7) {
  message: 'Timeout has occurred',
  info: { meta: null, lastValue: null, seen: 371 }
}

The code:

import {
  bindEagerlyTo,
  createContextToken,
  createServer,
  httpListener,
  HttpServerEffect,
  matchEvent,
  r,
  ServerEvent,
} from '@marblejs/core'
import {
  createWebSocketServer,
  mapToServer,
  webSocketListener,
  WebSocketServerConnection,
  WsEffect,
  WsServerEffect,
} from '@marblejs/websockets'
import { IO } from 'fp-ts/lib/IO'
import { merge } from 'rxjs'
import { mapTo, tap } from 'rxjs/operators'

const WebSocketServerToken = createContextToken<WebSocketServerConnection>('WebSocketServer')

export const hello$: WsEffect = event$ =>
  event$.pipe(matchEvent('HELLO'), mapTo({ type: 'HELLO', payload: 'Hello, world!' }))

const connection: WsServerEffect = (event, _ctx) =>
  event.pipe(
    matchEvent(ServerEvent.connection),
    tap(() => console.log('New client connection')),
  )

const webSocketServer = createWebSocketServer({
  event$: (...args) => merge(connection(...args)),
  listener: webSocketListener({
    effects: [hello$],
  }),
})

const upgrade$: HttpServerEffect = (event$, ctx) =>
  event$.pipe(
    matchEvent(ServerEvent.upgrade),
    mapToServer({
      path: '/api',
      server: ctx.ask(WebSocketServerToken),
    }),
  )

const api$ = r.pipe(
  r.matchPath('/'),
  r.matchType('GET'),
  r.useEffect(req$ => req$.pipe(mapTo({ body: 'Hello, world!' }))),
)

const server = createServer({
  dependencies: [bindEagerlyTo(WebSocketServerToken)(async () => await (await webSocketServer)())],
  event$: (...args) => merge(upgrade$(...args)),
  listener: httpListener({
    effects: [api$],
  }),
  port: 8007,
})

const main: IO<void> = async () => await (await server)()

main()

Expected behavior A TimeoutError should not kill the process and/or there should be a way to catch and handle this error.

Desktop (please complete the following information):

  • OS: Mac
  • Package + Version: @marblejs 3.5.0, rxjs 7.1.0, fp-ts 2.10.5
  • Node version: 14.16.1

Additional context

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
JozefFlakuscommented, Oct 19, 2021

@jan-kacina fix is here. Will release it under v3.5.2 then propagate it to v4.0.1

0reactions
JozefFlakuscommented, Oct 19, 2021

v3.5.2 and v4.0.1 released

Read more comments on GitHub >

github_iconTop Results From Across the Web

websocket error timeout triggering immediately - Stack Overflow
The problem arises if one of them is not connected to the network when the web app starts the websockets. In this scenario,...
Read more >
Both sides - websockets 10.4 documentation
it means that the WebSocket connection suffered from excessive latency and was closed after reaching the timeout of websockets' keepalive mechanism. You can ......
Read more >
New WebSocket implementation has no handshake timeout
Steps to reproduce: 1. Start a server which will not respond to the WebSocket handshake but not close the connection either.
Read more >
Why am I getting a crash at shutdown inside the thread pool?
A customer reported a crash in WinHTTP when their application shuts down a WebSocket. Specifically, it occurs when one of their DLL's global ......
Read more >
Preventing H12 Errors (Request Timeouts) - Heroku Dev Center
After you've identified which part of your slow transactions is causing the bottleneck, take steps to mitigate that slowness. For example: Move ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found