Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improve traces in the tests
Browse files Browse the repository at this point in the history
davesnx committed Jan 21, 2025

Verified

This commit was signed with the committer’s verified signature.
davesnx David Sancho
1 parent 7e21588 commit 2638785
Showing 2 changed files with 18 additions and 84 deletions.
92 changes: 14 additions & 78 deletions packages/reactDom/src/ReactDOM.ml
Original file line number Diff line number Diff line change
@@ -138,20 +138,6 @@ let render_suspense_fallback_error ~exn element =

let rec render_to_stream ~context_state element =
let rec render_element element =
Dream.log "Rendering element type: %s"
(match (element : React.element) with
| Empty -> "Empty"
| Client_component _ -> "Client_component"
| Provider _ -> "Provider"
| Consumer _ -> "Consumer"
| Fragment _ -> "Fragment"
| List _ -> "List"
| Upper_case_component _ -> "Upper_case_component"
| Lower_case_element _ -> "Lower_case_element"
| Text _ -> "Text"
| InnerHtml _ -> "InnerHtml"
| Async_component _ -> "Async_component"
| Suspense _ -> "Suspense");
match (element : React.element) with
| Empty -> Lwt.return Html.null
(* TODO: Check if this breaks in the client. Maybe should throw an error/exn? *)
@@ -162,20 +148,6 @@ let rec render_to_stream ~context_state element =
| List arr ->
let%lwt childrens = arr |> Array.to_list |> Lwt_list.map_p render_element in
Lwt.return (Html.list childrens)
| Upper_case_component component -> (
Dream.log "RENDER - Upper_case_component start";
try
Dream.log "RENDER - Upper_case_component try";
let element = component () in
Dream.log "RENDER - Upper_case_component got element";
render_element element
with
| React.Suspend _ as exn ->
Dream.log "RENDER - Upper_case_component caught suspension";
raise exn
| exn ->
Dream.log "RENDER - Upper_case_component caught other: %s" (Printexc.to_string exn);
raise exn)
| Lower_case_element { tag; attributes; _ } when Html.is_self_closing_tag tag ->
Lwt.return (Html.node tag (attributes_to_html attributes) [])
| Lower_case_element { key = _; tag; attributes; children } ->
@@ -184,89 +156,58 @@ let rec render_to_stream ~context_state element =
Lwt.return (Html.node tag html_attributes inner)
| Text text -> Lwt.return (Html.string text)
| InnerHtml text -> Lwt.return (Html.raw text)
| Upper_case_component component -> (
try
let element = component () in
render_element element
with exn -> raise_notrace exn)
| Async_component component -> (
Dream.log "Rendering element type: Async_component";
let promise = component () in
match Lwt.state promise with
| Lwt.Return element ->
Dream.log "Async_component already resolved";
render_element element
| Lwt.Fail exn ->
Dream.log "Async_component failed";
raise exn
| Lwt.Sleep ->
Dream.log "Async_component sleeping";
raise (React.Suspend (Any_promise promise)))
| Lwt.Return element -> render_element element
| Lwt.Fail exn -> raise_notrace exn
| Lwt.Sleep -> raise_notrace (React.Suspend (Any_promise promise)))
| Suspense { children; fallback; _ } -> (
try%lwt
let%lwt element = render_element children in
Lwt.return element
with
| React.Suspend (Any_promise promise) -> (
match Lwt.state promise with
| Lwt.Return _ ->
Dream.log "Promise already resolved, rendering immediately";
let%lwt _ = promise in
render_element children
| Lwt.Return _ -> render_element children
| Lwt.Fail exn ->
Dream.log "Promise failed";
let%lwt fallback_element = render_element fallback in
Lwt.return (render_suspense_fallback_error ~exn fallback_element)
| Lwt.Sleep ->
Dream.log "Promise pending, setting up streaming";
let%lwt fallback_element = render_element fallback in
let current_boundary_id = context_state.boundary_id in
let current_suspense_id = context_state.suspense_id in
context_state.boundary_id <- context_state.boundary_id + 1;
context_state.suspense_id <- context_state.suspense_id + 1;
Dream.log "About to increment waiting";
context_state.waiting <- context_state.waiting + 1;
Dream.log "Waiting count: %s" (string_of_int context_state.waiting);

Lwt.async (fun () ->
Dream.log "Started async resolution for boundary %d" current_boundary_id;
let%lwt _ = promise in
Dream.log "Promise resolved for boundary %d" current_boundary_id;
let%lwt resolved_html = render_with_resolved ~context_state children in
Dream.log "Children re-rendered in async";
context_state.waiting <- context_state.waiting - 1;
Dream.log "Waiting count after resolve: %d" context_state.waiting;
if not context_state.closed then (
Dream.log "Stream still open, pushing updates";
context_state.push (render_suspense_resolved_element ~id:current_suspense_id resolved_html);
context_state.push (inline_complete_boundary_script current_boundary_id current_suspense_id));
Dream.log "Updates pushed";
if context_state.waiting = 0 then (
context_state.closed <- true;
context_state.close ());
Dream.log "Async work complete";
Lwt.return_unit);
Dream.log "Returning fallback";
Lwt.return ());

Lwt.return (render_suspense_fallback ~boundary_id:current_boundary_id fallback_element))
| exn ->
Dream.log "Error in Suspense boundary: %s" (Printexc.to_string exn);
let%lwt fallback_element = render_element fallback in
Lwt.return (render_suspense_fallback_error ~exn fallback_element))
in

render_element element

and render_with_resolved ~context_state element =
Dream.log "RENDER - render_with_resolved start";
let rec render_element element =
Dream.log "Rendering element type: %s"
(match (element : React.element) with
| Empty -> "Empty"
| Client_component _ -> "Client_component"
| Provider _ -> "Provider"
| Consumer _ -> "Consumer"
| Fragment _ -> "Fragment"
| List _ -> "List"
| Upper_case_component _ -> "Upper_case_component"
| Lower_case_element _ -> "Lower_case_element"
| Text _ -> "Text"
| InnerHtml _ -> "InnerHtml"
| Async_component _ -> "Async_component"
| Suspense _ -> "Suspense");
match (element : React.element) with
| Empty -> Lwt.return Html.null
| Client_component _ -> Lwt.return Html.null
@@ -288,11 +229,10 @@ and render_with_resolved ~context_state element =
| Text text -> Lwt.return (Html.string text)
| InnerHtml text -> Lwt.return (Html.raw text)
| Async_component component -> (
Dream.log "RENDER - render_with_resolved Async_component";
let promise = component () in
match Lwt.state promise with
| Lwt.Return resolved -> render_element resolved
| Lwt.Fail exn -> raise exn
| Lwt.Fail exn -> raise_notrace exn
| Lwt.Sleep ->
let%lwt resolved = promise in
render_element resolved)
@@ -302,11 +242,7 @@ and render_with_resolved ~context_state element =

let renderToStream ?pipe:_ element =
let stream, push_to_stream, close = Push_stream.make () in
let push html =
Dream.log "PUSH";
Dream.log "%s" (Html.to_string html);
push_to_stream (Html.to_string html)
in
let push html = push_to_stream (Html.to_string html) in
let context_state = { push; close; closed = false; waiting = 0; boundary_id = 0; suspense_id = 0 } in
let abort () =
(* TODO: Needs to flush the remaining loading fallbacks as HTML, and React.js will try to render the rest on the client. *)
10 changes: 4 additions & 6 deletions packages/reactDom/test/test_renderToStream.ml
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ let suspense_with_always_throwing () =
Printexc.record_backtrace false;
let app () = React.Suspense.make ~fallback:(React.string "Loading...") ~children:(always_throwing_component ()) () in
let%lwt stream, _abort = ReactDOM.renderToStream (React.Upper_case_component app) in
(* and we need to enable it back, I guess! *)
(* and we need to enable it back for the next test *)
Printexc.record_backtrace true;
assert_stream stream
[ "<!--$!--><template data-msg=\"Failure(&quot;always throwing&quot;)\n\"></template>Loading...<!--/$-->" ]
@@ -188,20 +188,18 @@ let suspense_with_nested_suspense_with_error () =
~children:
(deffered_component ~seconds:0.02
~children:
(React.Suspense.make ~fallback:(React.string "Fallback 2") ~children:(always_throwing_component ()) ())
(let _ = Printexc.record_backtrace false in
React.Suspense.make ~fallback:(React.string "Fallback 2") ~children:(always_throwing_component ()) ())
())
()
in
Printexc.record_backtrace true;
let%lwt stream, _abort = ReactDOM.renderToStream (React.Upper_case_component app) in
assert_stream stream
[
"<!--$?--><template id=\"B:0\"></template>Fallback 1<!--/$-->";
"<div hidden id=\"S:0\"><div>Sleep 0.02 seconds<!-- -->, <!--$!--><template data-msg=\"Failure(&quot;always \
throwing&quot;)\n\
Raised at Stdlib__String.rindex_rec in file &quot;string.ml&quot;, line 145, characters 16-31\n\
Called from Stdlib__String.rindex in file &quot;string.ml&quot; (inlined), line 149, characters 17-46\n\
Called from Dream__server__Log.reporter.report.(fun) in file &quot;src/server/log.ml&quot;, line 195, \
characters 26-50\n\
\"></template>Fallback 2<!--/$--></div></div>";
rsc_script "$RC('B:0','S:0')";
]

0 comments on commit 2638785

Please sign in to comment.