From 1cc52976df8fe2665e8e6caa311fbbb8df08f8d9 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Thu, 28 Mar 2019 12:52:31 +0200 Subject: [PATCH] Add a new asyncDiscard replacement that traces recoverable errors and aborts on defects --- eth/async_utils.nim | 12 ++++++++++++ tests/test_async_utils.nim | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 eth/async_utils.nim create mode 100644 tests/test_async_utils.nim diff --git a/eth/async_utils.nim b/eth/async_utils.nim new file mode 100644 index 0000000..f456038 --- /dev/null +++ b/eth/async_utils.nim @@ -0,0 +1,12 @@ +import + chronos/asyncfutures2, chronicles + +proc traceAsyncErrors*(fut: FutureBase) = + fut.addCallback do (arg: pointer): + if not fut.error.isNil: + if fut.error[] of CatchableError: + trace "Async operation ended with a recoverable error", err = fut.error.msg + else: + fatal "Fatal exception reached", err = fut.error.msg + quit 1 + diff --git a/tests/test_async_utils.nim b/tests/test_async_utils.nim new file mode 100644 index 0000000..610678e --- /dev/null +++ b/tests/test_async_utils.nim @@ -0,0 +1,26 @@ +# TODO: Make this part of the test suite. +# We need to be able to test that a program fails in certain way. +# The testing framework from Chronicles can be extracted in a separate package. + +import + chronos, ../eth/async_utils + +type + SomeRecoverableError = object of CatchableError + SomeDefect = object of Defect + +proc failingAsyncProc(err: ref Exception = nil) {.async.} = + await sleepAsync(0) + if err != nil: + raise err + +proc main {.async.} = + type Error = + # Exception + SomeDefect + # SomeRecoverableError + traceAsyncErrors failingAsyncProc(newException(Error, "some exception")) + +waitFor main() +waitFor sleepAsync(2000) +