I recently trying to follow the Nim days 15: https://xmonader.github.io/nimdays/day15_tcprouter.html, but when I tried to set up the server to serve on port say 11000 and forward to my local hosted http server 6543, I just got all these kind of errors:
Async traceback:
  /Users/geohuz/Coding/nimlearn/portForwarding2.nim(69)                          portForwarding2
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncdispatch.nim(1874) runForever
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncdispatch.nim(1569) poll
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncdispatch.nim(1335) runOnce
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncdispatch.nim(210)  processPendingCallbacks
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncmacro.nim(34)      remoteHasDataNimAsyncContinue
  /Users/geohuz/Coding/nimlearn/portForwarding2.nim(37)                          remoteHasDataIter
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncmacro.nim(313)     send
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncmacro.nim(34)      sendNimAsyncContinue
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncnet.nim(446)       sendIter
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/pure/asyncdispatch.nim(1843) send
  /Users/geohuz/.choosenim/toolchains/nim-1.0.4/lib/system/fatal.nim(39)         sysFatal
Exception message: index out of bounds, the container is empty
Exception type:
 in remote has data loop
got data:
index out of bounds, the container is empty
and here is the code:
import  strformat, tables, json, strutils, sequtils, hashes, net, asyncdispatch, asyncnet, os, strutils, parseutils, deques, options, net
type ForwardOptions = object
  listenAddr*: string
  listenPort*: Port
  toAddr*: string
  toPort*: Port
type Forwarder = object of RootObj
  options*: ForwardOptions
proc processClient(this: ref Forwarder, client: AsyncSocket) {.async.} =
  let remote = newAsyncSocket(buffered=false)
  await remote.connect(this.options.toAddr, this.options.toPort)
  
  proc clientHasData() {.async.} =
    while not client.isClosed and not remote.isClosed:
      echo "in client has data loop"
      let data = await client.recv(1024)
      echo "got data: " & data
      try:
        await remote.send(data)
      except:
        echo getCurrentExceptionMsg()
    client.close()
    remote.close()
  
  proc remoteHasData() {.async.} =
    while not remote.isClosed and not client.isClosed:
      echo " in remote has data loop"
      let data = await remote.recv(1024)
      echo "got data: " & data
      try:
        await client.send(data)
      except:
        echo getCurrentExceptionMsg()
    client.close()
    remote.close()
  
  try:
    asyncCheck clientHasData()
    asyncCheck remoteHasData()
  except:
    echo getCurrentExceptionMsg()
proc serve(this: ref Forwarder) {.async.} =
  var server = newAsyncSocket(buffered=false)
  server.setSockOpt(OptReuseAddr, true)
  server.bindAddr(this.options.listenPort, this.options.listenAddr)
  echo fmt"Started tcp server... {this.options.listenAddr}:{this.options.listenPort} "
  server.listen()
  
  while true:
    let client = await server.accept()
    echo "..Got connection "
    
    asyncCheck this.processClient(client)
proc newForwarder(opts: ForwardOptions): ref Forwarder =
  result = new(Forwarder)
  result.options = opts
let opts = ForwardOptions(listenAddr:"127.0.0.1", listenPort:11000.Port, toAddr:"127.0.0.1", toPort:6543.Port)
var f = newForwarder(opts)
asyncCheck f.serve()
runForever()
Does it work if you remove the try/except blocks you added in ...HasData procedures? If it does, then the issue is as roughly explained here: https://nim-lang.org/docs/asyncdispatch.html#asynchronous-procedures-handling-exceptions
It seems like async and exceptions don't go very well together, at least not yet.
So I changed code as below:
proc processClient(this: ref Forwarder, client: AsyncSocket) {.async.} =
  let remote = newAsyncSocket(buffered=false)
  await remote.connect(this.options.toAddr, this.options.toPort)
  
  proc clientHasData() {.async.} =
    while not client.isClosed and not remote.isClosed:
      let recv = client.recv(1024)
      yield recv
      if recv.failed:
        echo "recv error........."
      else:
        let send = remote.send(recv.read)
        yield send
        if send.failed:
          echo "send error...."
    client.close()
    remote.close()
  
  proc remoteHasData() {.async.} =
    while not remote.isClosed and not client.isClosed:
      let recv = remote.recv(1024)
      yield recv
      if recv.failed:
        echo "recv error...."
      else:
        let send = client.send(recv.read)
        yield send
        if send.failed:
          echo "send error...."
    client.close()
    remote.close()
  
  try:
    asyncCheck clientHasData()
    asyncCheck remoteHasData()
  except:
    echo getCurrentExceptionMsg()
but I still got numerous "send error...", but the forwarding seems working.