2020-04-11 04:08:25 +00:00
|
|
|
# this module will be further extended in PR
|
|
|
|
# https://github.com/status-im/nim-libp2p/pull/107/
|
|
|
|
|
|
|
|
import chronos
|
|
|
|
import chronicles
|
|
|
|
import macros
|
|
|
|
|
2021-05-21 16:27:01 +00:00
|
|
|
type
|
|
|
|
# Base exception type for libp2p
|
|
|
|
LPError* = object of CatchableError
|
|
|
|
|
2021-06-02 13:39:10 +00:00
|
|
|
func toException*(e: cstring): ref LPError =
|
|
|
|
(ref LPError)(msg: $e)
|
|
|
|
|
|
|
|
func toException*(e: string): ref LPError =
|
|
|
|
(ref LPError)(msg: e)
|
|
|
|
|
|
|
|
# TODO: could not figure how to make it with a simple template
|
2021-05-21 16:27:01 +00:00
|
|
|
# sadly nim needs more love for hygienic templates
|
2020-04-11 04:08:25 +00:00
|
|
|
# so here goes the macro, its based on the proc/template version
|
|
|
|
# and uses quote do so it's quite readable
|
2023-11-16 15:54:34 +00:00
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/22936
|
|
|
|
macro checkFutures*[F](futs: seq[F], exclude: untyped = []): untyped =
|
2020-04-11 04:08:25 +00:00
|
|
|
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
|
2020-08-20 07:53:28 +00:00
|
|
|
debug "A future has failed, enable trace logging for details", error = exc.name
|
2020-08-04 13:22:05 +00:00
|
|
|
trace "Exception message", msg= exc.msg, stack = getStackTrace()
|
2020-04-11 04:08:25 +00:00
|
|
|
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]:
|
2020-05-26 07:08:09 +00:00
|
|
|
trace "A future has failed", error=exc.name, msg=exc.msg
|
2020-04-11 04:08:25 +00:00
|
|
|
break check
|
|
|
|
# We still don't abort but warn
|
2020-08-20 07:53:28 +00:00
|
|
|
debug "A future has failed, enable trace logging for details", error=exc.name
|
2020-05-18 13:49:49 +00:00
|
|
|
trace "Exception details", msg=exc.msg
|
2020-04-21 01:24:42 +00:00
|
|
|
|
2024-02-19 18:46:34 +00:00
|
|
|
proc allFuturesThrowing*[F: FutureBase](args: varargs[F]): Future[void] =
|
|
|
|
var futs: seq[F]
|
2020-04-21 01:24:42 +00:00
|
|
|
for fut in args:
|
|
|
|
futs &= fut
|
|
|
|
proc call() {.async.} =
|
2022-01-05 15:27:33 +00:00
|
|
|
var first: ref CatchableError = nil
|
2020-04-21 01:24:42 +00:00
|
|
|
futs = await allFinished(futs)
|
|
|
|
for fut in futs:
|
|
|
|
if fut.failed:
|
2020-04-21 13:10:47 +00:00
|
|
|
let err = fut.readError()
|
|
|
|
if err of Defect:
|
|
|
|
raise err
|
|
|
|
else:
|
2020-08-06 01:30:57 +00:00
|
|
|
if err of CancelledError:
|
|
|
|
raise err
|
2020-04-21 13:10:47 +00:00
|
|
|
if isNil(first):
|
|
|
|
first = err
|
|
|
|
if not isNil(first):
|
|
|
|
raise first
|
|
|
|
|
2020-04-21 01:24:42 +00:00
|
|
|
return call()
|
|
|
|
|
2020-05-18 13:49:49 +00:00
|
|
|
template tryAndWarn*(message: static[string]; body: untyped): untyped =
|
2020-04-21 01:24:42 +00:00
|
|
|
try:
|
|
|
|
body
|
2020-05-18 13:49:49 +00:00
|
|
|
except CancelledError as exc:
|
2020-07-08 00:33:05 +00:00
|
|
|
raise exc
|
2020-05-18 13:49:49 +00:00
|
|
|
except CatchableError as exc:
|
2020-08-20 07:53:28 +00:00
|
|
|
debug "An exception has ocurred, enable trace logging for details", name = exc.name, msg = message
|
2020-05-18 13:49:49 +00:00
|
|
|
trace "Exception details", exc = exc.msg
|