Error boundaries
Handle failed loaders and server results in the UI — inspired by Leptos <ErrorBoundary>, adapted for Resuma's SSR-first model.
Loader boundaries
Loaders run on the server before paint. Use load_boundary to branch on LoadValue::Ok | Err | Pending:
load_boundary(
use_user_load(),
|user| view! {
<h1>"Hello, " {user.name.clone()}</h1>
},
|err| view! {
<div class="error-banner">
"Could not load profile: " {err.message.clone()}
</div>
},
|| view! { <p aria-busy="true">"Loading profile…"</p> },
)Result fallback
For synchronous Result<View, E> branches inside a component:
let panel = match build_panel() {
Ok(v) => v,
Err(e) => view! { <p class="error">{e}</p> },
};
// Or with the helper:
error_boundary(build_panel(), |msg| view! {
<p class="error">{msg}</p>
})Server actions & client errors
Use __resuma.safeAction(name, args) in js! for Result-style handling without try/catch — like Leptos error boundaries for RPC:
onClick={js!(async (_, __resuma) => {
const res = await __resuma.safeAction("current_time", [input]);
if (res.ok) {
okEl.textContent = res.value;
} else {
errEl.textContent = res.error;
}
})}Progressive enhancement
Forms with <Form submit={…}> still work without JS. Field errors render via .resuma-field-error when the runtime intercepts the POST.