summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/asyncdispatch.nim25
-rw-r--r--lib/pure/net.nim2
-rw-r--r--lib/pure/rawsockets.nim2
-rw-r--r--lib/windows/winlean.nim1
4 files changed, 24 insertions, 6 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 752c19534..dea17d146 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -41,7 +41,8 @@ type
     cb: proc () {.closure,gcsafe.}
     finished: bool
     error*: ref EBase
-    when defined(debug):
+    errorStackTrace*: string
+    when not defined(release):
       stackTrace: string ## For debugging purposes only.
       id: int
       fromProc: string
@@ -57,14 +58,14 @@ proc newFuture*[T](fromProc: string = "unspecified"): PFuture[T] =
   ## that this future belongs to, is a good habit as it helps with debugging.
   new(result)
   result.finished = false
-  when defined(debug):
+  when not defined(release):
     result.stackTrace = getStackTrace()
     result.id = currentID
     result.fromProc = fromProc
     currentID.inc()
 
 proc checkFinished[T](future: PFuture[T]) =
-  when defined(debug):
+  when not defined(release):
     if future.finished:
       echo("<-----> ", future.id, " ", future.fromProc)
       echo(future.stackTrace)
@@ -101,6 +102,8 @@ proc fail*[T](future: PFuture[T], error: ref EBase) =
   checkFinished(future)
   future.finished = true
   future.error = error
+  future.errorStackTrace =
+    if getStackTrace(error) == "": getStackTrace() else: getStackTrace(error)
   if future.cb != nil:
     future.cb()
   else:
@@ -128,6 +131,15 @@ proc `callback=`*[T](future: PFuture[T],
   ## If future has already completed then ``cb`` will be called immediately.
   future.callback = proc () = cb(future)
 
+proc echoOriginalStackTrace[T](future: PFuture[T]) =
+  # TODO: Come up with something better.
+  when not defined(release):
+    echo("Original stack trace in ", future.fromProc, ":")
+    if not future.errorStackTrace.isNil() and future.errorStackTrace != "":
+      echo(future.errorStackTrace)
+    else:
+      echo("Empty or nil stack trace.")
+
 proc read*[T](future: PFuture[T]): T =
   ## Retrieves the value of ``future``. Future must be finished otherwise
   ## this function will fail with a ``EInvalidValue`` exception.
@@ -135,6 +147,7 @@ proc read*[T](future: PFuture[T]): T =
   ## If the result of the future is an error then that error will be raised.
   if future.finished:
     if future.error != nil:
+      echoOriginalStackTrace(future)
       raise future.error
     when T isnot void:
       return future.value
@@ -165,6 +178,7 @@ proc asyncCheck*[T](future: PFuture[T]) =
   future.callback =
     proc () =
       if future.failed:
+        echoOriginalStackTrace(future)
         raise future.error
 
 type
@@ -438,7 +452,10 @@ when defined(windows) or defined(nimdoc):
               copyMem(addr data[0], addr dataBuf.buf[0], bytesCount)
               retFuture.complete($data)
           else:
-            retFuture.fail(newException(EOS, osErrorMsg(errcode)))
+            if flags.isDisconnectionError(errcode):
+              retFuture.complete("")
+            else:
+              retFuture.fail(newException(EOS, osErrorMsg(errcode)))
         if dataBuf.buf != nil:
           dealloc dataBuf.buf
           dataBuf.buf = nil
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index ddc2bbe2d..5f83b1dea 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -361,7 +361,7 @@ proc isDisconnectionError*(flags: set[TSocketFlags],
   when useWinVersion:
     TSocketFlags.SafeDisconn in flags and
       lastError.int32 in {WSAECONNRESET, WSAECONNABORTED, WSAENETRESET,
-                          WSAEDISCON}
+                          WSAEDISCON, ERROR_NETNAME_DELETED}
   else:
     TSocketFlags.SafeDisconn in flags and
       lastError.int32 in {ECONNRESET, EPIPE, ENETRESET} 
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index d96741846..fea09dfa2 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -22,7 +22,7 @@ const useWinVersion = defined(Windows) or defined(nimdoc)
 when useWinVersion:
   import winlean
   export WSAEWOULDBLOCK, WSAECONNRESET, WSAECONNABORTED, WSAENETRESET,
-         WSAEDISCON
+         WSAEDISCON, ERROR_NETNAME_DELETED
 else:
   import posix
   export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL,
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index dcae6ffaf..09696b67f 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -664,6 +664,7 @@ const
   WSAEDISCON* = 10101
   WSAENETRESET* = 10052
   WSAETIMEDOUT* = 10060
+  ERROR_NETNAME_DELETED* = 64
 
 proc CreateIoCompletionPort*(FileHandle: THANDLE, ExistingCompletionPort: THANDLE,
                              CompletionKey: DWORD,