# Using OCaml-5.3's caml\_callback\_res function

**URL:** <https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601>\
**Category:** Learning\
**Created:** [May 4, 2025, 10:37pm UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601 "2025-05-04T22:37:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [May 4, 2025, 10:37pm UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601/1 "2025-05-04T22:37:19Z")

</div>

One of my OCaml projects employs some C stub code which applies OCaml callbacks previously registered with `Callback.register`, using the `caml_callback_exn` function. If an OCaml callback raises an exception this is detected by applying the `Is_exception_result` macro to the return value of `caml_callback_exn` and the exception object is obtained using the `Extract_exception` macro. The program does not necessarily terminate or reraise in view of such an exception: instead the issue is logged, making use of the `caml_format_exception` function to provide a textual representation of the exception object, and in some cases then allowed to continue without reraising - in particular where the code is executing in an event loop and there is no OCaml code which can sensibly catch the exception further down the stack if it were to be reraised.

I am aware of the problems with `caml_callback_exn` (which are dealt with in the manner recommended in the manual), and although the code is correct I have been considering moving to OCaml-5.3’s new `caml_callback_res` function, which returns a `caml_result` type. However I have not managed to work out how to obtain the exception object from its return value in order to apply `caml_format_exception` to log it.

According to the documentation, the public API for the `caml_result` type comprises the `Result_value` and `Result_exception` macros to construct `caml_result` objects, and the `caml_result_is_exception` and `caml_get_value_or_raise` functions to consume them. In the case of an exception the C exception object in fact resides in the ‘data’ field of the `caml_result_private` C struct, but as the name suggests that struct’s fields are not part of the public API. The `caml_get_value_or_raise` function is available, but if the `caml_result_is_exception` function returns true then it always reraises, which is not what I want.

Does anyone know if there is any way around this without using non-public API?

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [May 5, 2025, 5:31am UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601/2 "2025-05-05T05:31:54Z")

</div>

> [@cvine](#):
>
> Does anyone know if there is any way around this without using non-public API?

As you point out, this does not seem possible at the moment. I think an issue upstream [GitHub · Where software is built](https://github.com/ocaml/ocaml/issues) would be useful.

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [May 5, 2025, 7:33am UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601/3 "2025-05-05T07:33:55Z")

</div>

This sounds indeed like an unfortunate blind spot on my part in [#13013](https://github.com/ocaml/ocaml/pull/13013), apologies.

My main reason to leave some parts of the representation abstract/private was to leave the door open to supporting effect handlers in the feature – a “third case” could be added to the structure, which is a pair of an effect operation and a captured continuation. Presumably in this case `get_value_or_raise` would propagate the effect up to the caller. In this case there would not necessarily be an exception payload to return.

I’m not sure what would be a reasonable API to let users access the exception payload, if/when we want to leave the door open to such an extension.

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [May 5, 2025, 7:41am UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601/4 "2025-05-05T07:41:24Z")

</div>

> [@gasche](#):
>
> I’m not sure what would be a reasonable API to let users access the exception payload, if/when we want to leave the door open to such an extension.

Wouldn’t it have been better to have `caml_result_is_exception` return a `value*`, with the exception value (if any) or `NULL` otherwise?

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [May 5, 2025, 8:51am UTC](https://discuss.ocaml.org/t/using-ocaml-5-3s-caml-callback-res-function/16601/5 "2025-05-05T08:51:30Z")

</div>

I have raised an issue upstream at [caml\_callback\_res does not provide access to exception payload · Issue #14016 · ocaml/ocaml · GitHub](https://github.com/ocaml/ocaml/issues/14016) . I have made the issue a feature request rather than a bug. It seems to be a bit of both, so please change this if you think that would better express the point.
