From 29064fb19db505f9f5150321a5eab0cfbb255c72 Mon Sep 17 00:00:00 2001 From: Yawar Amin Date: Sun, 7 Sep 2025 20:59:26 -0400 Subject: [PATCH 1/2] Add note about Lwt error handling Fix #389 --- example/5-promise/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/example/5-promise/README.md b/example/5-promise/README.md index 826c971c..3db22f88 100644 --- a/example/5-promise/README.md +++ b/example/5-promise/README.md @@ -87,6 +87,15 @@ For example, `let%lwt` is equivalent to... We will stick to `let%lwt` in the examples and keep things tidy. +> [!NOTE] +> You may be wondering if the `let%lwt`, `try%lwt`, etc. constructs are really +> needed here. If you remove them, the example may appear to work the same way. +> However, this is purely coincidental, because we are raising a normal exception +> with `raise`. If the handler happened to return a rejected promise instead of +> raising, we would have observed incorrect results. Therefore, it is safer to +> use the Lwt constructs in Dream handlers and middlewares to ensure all errors +> are handled correctly. +
**Next steps:** From 288a8298eeea0881c60ee282fabc2c22a5cc9e6c Mon Sep 17 00:00:00 2001 From: Sebastian Willenbrink Date: Mon, 12 Jan 2026 19:32:54 +0100 Subject: [PATCH 2/2] Add note about race condition --- example/5-promise/README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/example/5-promise/README.md b/example/5-promise/README.md index 3db22f88..45866a2b 100644 --- a/example/5-promise/README.md +++ b/example/5-promise/README.md @@ -90,11 +90,14 @@ We will stick to `let%lwt` in the examples and keep things tidy. > [!NOTE] > You may be wondering if the `let%lwt`, `try%lwt`, etc. constructs are really > needed here. If you remove them, the example may appear to work the same way. -> However, this is purely coincidental, because we are raising a normal exception -> with `raise`. If the handler happened to return a rejected promise instead of -> raising, we would have observed incorrect results. Therefore, it is safer to -> use the Lwt constructs in Dream handlers and middlewares to ensure all errors -> are handled correctly. +> However, this is not true for two reasons: +> Firstly, `let%lwt` awaits the computation before evaluating the next expression. +> Just `let response = ...` causes a race condition: `inner_handler` is started but +> not awaited and might access `successful` before or after it is incremented. +> Secondly, we are raising a normal exception with `raise`. If the handler happened +> to return a rejected promise instead of raising, we would have observed incorrect +> results. Therefore, it is safer to use the Lwt constructs in Dream handlers and +> middlewares to ensure all errors are handled correctly.