Skip to content

Commit

Permalink
avoid warning in noCancel with non-raising future (status-im#540)
Browse files Browse the repository at this point in the history
  • Loading branch information
arnetheduck authored May 6, 2024
1 parent 52b02b9 commit 1ff81c6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
19 changes: 12 additions & 7 deletions chronos/internal/asyncfutures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1031,19 +1031,24 @@ proc noCancel*[F: SomeFuture](future: F): auto = # async: (raw: true, raises: as
let retFuture = newFuture[F.T]("chronos.noCancel(T)",
{FutureFlag.OwnCancelSchedule})
template completeFuture() =
const canFail = when declared(InternalRaisesFutureRaises):
InternalRaisesFutureRaises isnot void
else:
true

if future.completed():
when F.T is void:
retFuture.complete()
else:
retFuture.complete(future.value)
elif future.failed():
when F is Future:
retFuture.fail(future.error, warn = false)
when declared(InternalRaisesFutureRaises):
when InternalRaisesFutureRaises isnot void:
retFuture.fail(future.error, warn = false)
else:
raiseAssert("Unexpected future state [" & $future.state & "]")
when canFail: # Avoid calling `failed` on non-failing raises futures
if future.failed():
retFuture.fail(future.error, warn = false)
else:
raiseAssert("Unexpected future state [" & $future.state & "]")
else:
raiseAssert("Unexpected future state [" & $future.state & "]")

proc continuation(udata: pointer) {.gcsafe.} =
completeFuture()
Expand Down
32 changes: 31 additions & 1 deletion tests/testmacro.nim
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ suite "Exceptions tracking":

noraises()

test "Nocancel errors":
test "Nocancel errors with raises":
proc testit {.async: (raises: [ValueError, CancelledError]).} =
await sleepAsync(5.milliseconds)
raise (ref ValueError)()
Expand All @@ -535,6 +535,36 @@ suite "Exceptions tracking":

noraises()

test "Nocancel with no errors":
proc testit {.async: (raises: [CancelledError]).} =
await sleepAsync(5.milliseconds)

proc test {.async: (raises: []).} =
await noCancel testit()

proc noraises() {.raises: [].} =
let f = test()
waitFor(f.cancelAndWait())
waitFor(f)

noraises()

test "Nocancel errors without raises":
proc testit {.async.} =
await sleepAsync(5.milliseconds)
raise (ref ValueError)()

proc test {.async.} =
await noCancel testit()

proc noraises() =
expect(ValueError):
let f = test()
waitFor(f.cancelAndWait())
waitFor(f)

noraises()

test "Defect on wrong exception type at runtime":
{.push warning[User]: off}
let f = InternalRaisesFuture[void, (ValueError,)]()
Expand Down

0 comments on commit 1ff81c6

Please sign in to comment.