Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support catchAsync for using if/without and await #64

Open
emizzle opened this issue Feb 20, 2025 · 1 comment
Open

Support catchAsync for using if/without and await #64

emizzle opened this issue Feb 20, 2025 · 1 comment

Comments

@emizzle
Copy link

emizzle commented Feb 20, 2025

Perhaps the best place to put catchAsync would be in questionable, since it seems to be the most useful when combining without/if and await. Normally, using catch with await will catch all CatchableErrors, including CancelledError, which would prevent cancellation propagation, for example:

without collateral =?
      await sales.context.market.slotCollateral(data.requestId, data.slotIndex).catch:

In this example, slotCollateral return ?UInt256, so we use the binding features of questionable, here, and want to also catch any errors in the process.

This is where something like catchAsync could come into play, which could be used without fear of swallowing CancelledError, for example:

without collateral =?
      await sales.context.market.slotCollateral(data.requestId, data.slotIndex).catchAsync:

catchAsync could be implemented like this (tested inside of nim-codex):

template catchAsync*(body: typed): Result[type(body), ref CatchableError] =
  ## Catch exceptions for `body` containing `await` and store them in the
  ## Result, propagating cancellations.
  ##
  ## ```
  ## let r = catchAsync: await someAsyncFuncThatMayRaise()
  ## ```
  type R = Result[type(body), ref CatchableError]

  try:
    when type(body) is void:
      body
      R.ok()
    else:
      R.ok(body)
  except CancelledError as eCancelled:
    raise eCancelled
  except CatchableError as eResultPrivate:
    R.err(eResultPrivate)

It was determined not to be suited for nim-results (arnetheduck/nim-results#54), and as a possibility might eventually be included as a feature set to using Result with nim-chronos.

@cheatfate
Copy link

cheatfate commented Mar 6, 2025

My personal opinion on this that Future[T, E] is superset of Result[T, E] (it actually could provide all the features of Result[T, E] and add more). Also this is well-known fact that encapsulating big amounts of data into Result[T, E] is extremely ineffective, so even check for an error will cause Nim compiler expand value, so usage of Result[seq[byte], E] is bad idea for performance.

So i do not like idea to have constructions Result[Future[T, E], E] inside nim-chronos codebase, but you can always use this templates in your own codebase.

P.S. sorry i was followed original issue in chronos repo to here and i thought that i responding it in nim-chronos issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants