A common problem that I personally had when developing async code in OCaml is that both
Async leads to useless stack traces. When using
lwt_ppx that is handled by the ppx, but the same is not possible with
If you want to solve that, you can use ppx_let_locs, it will detect your calls and when there is a replacement function available that would allow stack traces to be enhanced it will enhance that by default for you.
Everytime an ident is applied it tries to find a
ident_backtrace version of it, if that is present and it has the right signature, the PPX will then apply the backtraced one with the additional argument. This means it also works with operators, like
>>=_backtrace, as they’re just normal function application.
For letop there is a special case, the signature of the letop must be slightly different to ensure that the typing order was not changed, essentially the
let*_backtrace must have the following signature
(exn -> exn * 'a) -> 'b -> 'c.
To achieve that this is actually a typed PPX, which runs a slightly patched version of the OCaml typechecker, then untype it and pass to the OCaml compiler. This implies a couple of things:
- it needs to be executed as
(staged_pps ppx_let_locs)on dune
- versions must be explicitly supported, for now only 4.10 and 4.12 are supported, if you need any other version feel free to request.
- it can be quite slow on some codebases
To solve the above problems, an important property is that, assuming the backtraced version behaves identically to the non backtraced one, it is in theory a noop, as removing or adding the PPX should not change the behavior of the code. So it can be used only for development or for production, as adding or removing the PPX will not break your code.
Currently it seems like Async doesn’t provide anything similar to
Async.try_with also looses the stack trace, so I would love help in this area.
As you can see, on the second stack trace you can find out that it was actually being called on