@dom96 is right, it can be done like this:
macro withTran(db, body: untyped): untyped =
quote do:
block:
proc action(`db`: apgPoolConnection) {.async.} =
`body`
let fut = doTransaction(action)
yield fut
The following code is extracted from asyncpg.
template withConnection*(pool: apgPool, conn, body: untyped) =
## Retrieves first available connection from pool, assign it
## to variable with name `conn`. You can use this connection
## inside withConnection code
The document is about exception raised by async proc, my problem is about the
exception raised by called proc between async code using resource, they are
something different. Maybe I can wrapper the body with a proc which turn
exception into return value.
@dom96 Thanks. The code seems works, but it doesn't. db.close() seems executed
before the code 'block', this is the error message:
asyncdispatch.nim(1492) waitFor
asyncdispatch.nim(1496) poll
asyncdispatch.nim(292) runOnce
Error: unhandled exception: No handles or
@adrianv
[this](https://nim-lang.org/docs/asyncdispatch.html#asynchronous-procedures-handling-exceptions)
Nim's 'async' macro rewrites the code so that it becomes iterable/etc where
needed.
[https://nim-lang.org/docs/asyncdispatch.html#17](https://nim-lang.org/docs/asyncdispatch.html#17)
I think what Dom's doing here is giving a slightly desugared version of what
the 'async' macro would normally
What does yield inside a template do ? The documentations says yield is only
valid inside an iterator.
Yes, you can do this:
template withDb(body: untyped) =
let dbFut = open(...)
yield dbFut
let db = dbFut.read()
defer: close(db)
block:
body
We can create template with like this:
template withFile(name: string, body: untyped) =
let fh = open(name, ...)
defer: close(fh)
block:
body
But when template contain await, the compiler will complain the 'await' is
undeclared identifier. The