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.
38 lines
876 B
Nim
38 lines
876 B
Nim
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()
|