mirror of
https://github.com/vacp2p/nim-libp2p-experimental.git
synced 2025-01-10 10:25:54 +00:00
ccd019b328
* use stream directly in chronosstream for now, chronos.AsyncStream is not used to provide any features on top of chronos.Stream, so in order to simplify the code, chronosstream can be used directly. In particular, the exception handling is broken in the current chronosstream - opening and closing the stream is simplified this way as well. A future implementation that actually takes advantage of the AsyncStream features would wrap AsyncStream instead as a separate lpstream implementation, leaving this one as-is. * work around chronos exception type issue
63 lines
1.8 KiB
Nim
63 lines
1.8 KiB
Nim
# this module will be further extended in PR
|
|
# https://github.com/status-im/nim-libp2p/pull/107/
|
|
|
|
import chronos
|
|
import chronicles
|
|
import macros
|
|
|
|
# could not figure how to make it with a simple template
|
|
# sadly nim needs more love for hygenic templates
|
|
# so here goes the macro, its based on the proc/template version
|
|
# and uses quote do so it's quite readable
|
|
|
|
macro checkFutures*[T](futs: seq[Future[T]], exclude: untyped = []): untyped =
|
|
let nexclude = exclude.len
|
|
case nexclude
|
|
of 0:
|
|
quote do:
|
|
for res in `futs`:
|
|
if res.failed:
|
|
let exc = res.readError()
|
|
# We still don't abort but warn
|
|
warn "Something went wrong in a future", error=exc.name, msg = exc.msg
|
|
else:
|
|
quote do:
|
|
for res in `futs`:
|
|
block check:
|
|
if res.failed:
|
|
let exc = res.readError()
|
|
for i in 0..<`nexclude`:
|
|
if exc of `exclude`[i]:
|
|
trace "Ignoring an error (no warning)", error=exc.name, msg = exc.msg
|
|
break check
|
|
# We still don't abort but warn
|
|
warn "Something went wrong in a future", error=exc.name, msg = exc.msg
|
|
|
|
proc allFuturesThrowing*[T](args: varargs[Future[T]]): Future[void] =
|
|
var futs: seq[Future[T]]
|
|
for fut in args:
|
|
futs &= fut
|
|
proc call() {.async.} =
|
|
var first: ref Exception = nil
|
|
futs = await allFinished(futs)
|
|
for fut in futs:
|
|
if fut.failed:
|
|
let err = fut.readError()
|
|
if err of Defect:
|
|
raise err
|
|
else:
|
|
if isNil(first):
|
|
first = err
|
|
if not isNil(first):
|
|
raise first
|
|
|
|
return call()
|
|
|
|
template tryAndWarn*(msg: static[string]; body: untyped): untyped =
|
|
try:
|
|
body
|
|
except CancelledError as ex:
|
|
raise ex
|
|
except CatchableError as ex:
|
|
warn "ignored an error", name=ex.name, msg=msg
|