summary refs log tree commit diff stats
path: root/tests/async
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2014-08-09 17:13:22 +0100
committerDominik Picheta <dominikpicheta@googlemail.com>2014-08-09 17:13:22 +0100
commit4f5f98f0b1693a221bd3a2087bddf7e6ac350387 (patch)
tree93ff56f70b8995e249b0f38e9467f524de73fe77 /tests/async
parentfd086abb43d606188920c841bcd4abbed770e7d6 (diff)
downloadNim-4f5f98f0b1693a221bd3a2087bddf7e6ac350387.tar.gz
Fixes incorrect async exception handling. Adds sleepAsync.
The tasyncexceptions test has been added which tests for this incorrect
exception handling behaviour. The problem was that the exception was
raised inside a callback which was called from a previously finished async
procedure. This caused a "Future already finished" error. The fix was to
simply reraise the exception if the retFutureSym is already finished.

sleepAsync was added to help with the reproduction of this test. It should
also be useful for users however.

Finally some debug information was added to futures to help with future
bugs.
Diffstat (limited to 'tests/async')
-rw-r--r--tests/async/tasyncexceptions.nim38
1 files changed, 38 insertions, 0 deletions
diff --git a/tests/async/tasyncexceptions.nim b/tests/async/tasyncexceptions.nim
new file mode 100644
index 000000000..9474fbae8
--- /dev/null
+++ b/tests/async/tasyncexceptions.nim
@@ -0,0 +1,38 @@
+discard """
+  file: "tasyncexceptions.nim"
+  exitcode: 1
+  outputsub: "Error: unhandled exception: foobar [E_Base]"
+"""
+import asyncdispatch
+
+proc accept(): PFuture[int] {.async.} =
+  await sleepAsync(100)
+  result = 4
+
+proc recvLine(fd: int): PFuture[string] {.async.} =
+  await sleepAsync(100)
+  return "get"
+
+proc processClient(fd: int) {.async.} =
+  # these finish synchronously, we need some async delay to emulate this bug.
+  var line = await recvLine(fd)
+  var foo = line[0]
+  if foo == 'g':
+    raise newException(EBase, "foobar")
+  
+
+proc serve() {.async.} =
+
+  while true:
+    var fut = await accept()
+    await processClient(fut)
+
+when isMainModule:
+  var fut = serve()
+  fut.callback =
+    proc () =
+      if fut.failed:
+        # This test ensures that this exception crashes the application
+        # as it is not handled.
+        raise fut.error
+  runForever()