There isn't such a test. That is the expected behavior, because cancelation causes an ordinary failure of the inner promise returned by
Lwt_unix.sleep, and the (weird?) semantics of
finalize take over after that. We will add a test for the sake of thoroughness. Again, I don't know if this is how it should be, but that's how it is...
Lwt.catch is also weird with
cancel, in that the cancelation "failure" can be captured by the exception handler:
(* In [p' = Lwt.catch (fun () -> p) f], if [p] is cancelable, canceling
[p'] propagates to [p], and then the cancelation exception can be
"intercepted" by [f], which can complete [p'] in an arbitrary way. *)
test "catch: task, pending, canceled" begin fun () ->
let p, _ = Lwt.task () in
let p' =
(fun () -> p)
(fun exn -> Lwt.return "foo")
(Lwt.state p = Lwt.Fail Lwt.Canceled &&
Lwt.state p' = Lwt.Return "foo") (* <-------- !!!! *)
Regarding the hook, it does seem like handling "double faults" in some way is desirable.
I think this is a much-discussed problem in all languages that have
finally blocks, i.e. Python, Java, etc., so the first thing to do is probably to mine them for ideas. There are probably strong arguments for one behavior or another, and we should find them, save links, and document it all.