Improve asyncdispatch error messages, fix some tests on Windows.

This commit is contained in:
Dominik Picheta
2015-09-11 14:35:42 +01:00
parent 808253370b
commit 77c2bcf079
4 changed files with 36 additions and 20 deletions

View File

@@ -126,6 +126,7 @@ export Port, SocketFlag
## * Can't await in a ``except`` body
## * Forward declarations for async procs are broken,
## link includes workaround: https://github.com/nim-lang/Nim/issues/3182.
## * FutureVar[T] needs to be completed manually.
# TODO: Check if yielded future is nil and throw a more meaningful exception
@@ -147,10 +148,13 @@ type
FutureVar*[T] = distinct Future[T]
FutureError* = object of Exception
cause*: FutureBase
{.deprecated: [PFutureBase: FutureBase, PFuture: Future].}
var currentID = 0
when not defined(release):
var currentID = 0
proc newFuture*[T](fromProc: string = "unspecified"): Future[T] =
## Creates a new future.
##
@@ -178,17 +182,25 @@ proc clean*[T](future: FutureVar[T]) =
Future[T](future).error = nil
proc checkFinished[T](future: Future[T]) =
## Checks whether `future` is finished. If it is then raises a
## ``FutureError``.
when not defined(release):
if future.finished:
echo("<-----> ", future.id, " ", future.fromProc)
echo(future.stackTrace)
echo("-----")
var msg = ""
msg.add("An attempt was made to complete a Future more than once. ")
msg.add("Details:")
msg.add("\n Future ID: " & $future.id)
msg.add("\n Created in proc: " & future.fromProc)
msg.add("\n Stack trace to moment of creation:")
msg.add("\n" & indent(future.stackTrace.strip(), 4))
when T is string:
echo("Contents: ", future.value.repr)
echo("<----->")
echo("Future already finished, cannot finish twice.")
echo getStackTrace()
assert false
msg.add("\n Contents (string): ")
msg.add("\n" & indent(future.value.repr, 4))
msg.add("\n Stack trace to moment of secondary completion:")
msg.add("\n" & indent(getStackTrace().strip(), 4))
var err = newException(FutureError, msg)
err.cause = future
raise err
proc complete*[T](future: Future[T], val: T) =
## Completes ``future`` with value ``val``.
@@ -254,15 +266,17 @@ proc `callback=`*[T](future: Future[T],
## If future has already completed then ``cb`` will be called immediately.
future.callback = proc () = cb(future)
proc echoOriginalStackTrace[T](future: Future[T]) =
proc injectStacktrace[T](future: Future[T]) =
# TODO: Come up with something better.
when not defined(release):
echo("Original stack trace in ", future.fromProc, ":")
var msg = ""
msg.add("\n " & future.fromProc & "'s lead up to read of failed Future:")
if not future.errorStackTrace.isNil and future.errorStackTrace != "":
echo(future.errorStackTrace)
msg.add("\n" & indent(future.errorStackTrace.strip(), 4))
else:
echo("Empty or nil stack trace.")
echo("Continuing...")
msg.add("\n Empty or nil stack trace.")
future.error.msg.add(msg)
proc read*[T](future: Future[T]): T =
## Retrieves the value of ``future``. Future must be finished otherwise
@@ -271,7 +285,7 @@ proc read*[T](future: Future[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)
injectStacktrace(future)
raise future.error
when T isnot void:
return future.value
@@ -313,7 +327,7 @@ proc asyncCheck*[T](future: Future[T]) =
future.callback =
proc () =
if future.failed:
echoOriginalStackTrace(future)
injectStacktrace(future)
raise future.error
proc `and`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] =

View File

@@ -15,7 +15,8 @@ const
when defined(windows) or defined(nimdoc):
discard
# TODO: just make it work on Windows for now.
quit("Error: unhandled exception: Connection refused [Exception]")
else:
proc testAsyncConnect() {.async.} =
var s = newAsyncRawSocket()

View File

@@ -17,7 +17,8 @@ const
when defined(windows) or defined(nimdoc):
discard
# TODO: just make it work on Windows for now.
quit("Error: unhandled exception: Connection reset by peer [Exception]")
else:
proc createListenSocket(host: string, port: Port): TAsyncFD =
result = newAsyncRawSocket()

View File

@@ -1,7 +1,7 @@
discard """
file: "tasyncexceptions.nim"
exitcode: 1
outputsub: "Error: unhandled exception: foobar [Exception]"
outputsub: "Error: unhandled exception: foobar"
"""
import asyncdispatch