mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 05:53:22 +00:00
Improve asyncdispatch error messages, fix some tests on Windows.
This commit is contained in:
@@ -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] =
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
discard """
|
||||
file: "tasyncexceptions.nim"
|
||||
exitcode: 1
|
||||
outputsub: "Error: unhandled exception: foobar [Exception]"
|
||||
outputsub: "Error: unhandled exception: foobar"
|
||||
"""
|
||||
import asyncdispatch
|
||||
|
||||
|
||||
Reference in New Issue
Block a user