fix(calendar): hoist timezone reads out of use_signal initialisers (MAPPS-299) #339
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/mokosh-apps!339
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/MAPPS-299-calendar-hook-violation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
QA repro nailed the Calendar "+ New Appointment" crash to:
BorrowMutErrorat dioxus-core scope_context.rs:343 with"using a hook inside a hook" (rules-of-hooks violation).
signal during teardown.
Root cause of the primary panic. AppointmentFormModal had four
use_signalinitialisers that called timezone-aware conversion helpers(
utc_to_datetime_local_value,utc_to_date_value). Those helpersreach into
user_timezone(), which callstry_use_context::<Signal<AuthContext>>()- itself a hook. Running ahook inside another hook's initialiser is the panic the trace
described. Dispatch's parent happens to dodge it because its mount path
hits the modal with the auth context in a different borrow state, so
the same code looked fine in one surface and crashed in the other.
Fix: hoist the four timezone conversions above the
use_signalcallsinto local bindings (
init_start_local,init_end_local,init_start_date,init_end_date) and pass plainStrings into theinitialisers. The hooks now run with no inner hook calls.
Root cause of the secondary panic.
use_unsaved_guardinstalls abeforeunloadclosure that capturesdirty: ReadSignal<bool>andcalls
dirty.read()when the browser fires the event. The listenerstays installed across component teardown (wasm cannot detach a
Closure-backed listener once a sibling component has alreadypanicked), so the signal can be dropped by the time the event fires;
Signal::readthen panics withValueDroppedError, which surfaces asthe secondary trace QA captured.
Fix: use
try_readinstead ofreadand treat a dropped signal as"not dirty" - no prompt, no panic.
Acceptance criteria from MAPPS-299:
wasm runtime (Calendar).
console_error_panic_hook(PR #284, unchanged).#MAPPS-299
QA repro nailed the Calendar "+ New Appointment" crash to: - Primary: `BorrowMutError` at dioxus-core scope_context.rs:343 with "using a hook inside a hook" (rules-of-hooks violation). - Secondary: panic at hooks/unsaved_guard.rs:56 unwrapping a dropped signal during teardown. Root cause of the primary panic. AppointmentFormModal had four `use_signal` initialisers that called timezone-aware conversion helpers (`utc_to_datetime_local_value`, `utc_to_date_value`). Those helpers reach into `user_timezone()`, which calls `try_use_context::<Signal<AuthContext>>()` - itself a hook. Running a hook inside another hook's initialiser is the panic the trace described. Dispatch's parent happens to dodge it because its mount path hits the modal with the auth context in a different borrow state, so the same code looked fine in one surface and crashed in the other. Fix: hoist the four timezone conversions above the `use_signal` calls into local bindings (`init_start_local`, `init_end_local`, `init_start_date`, `init_end_date`) and pass plain `String`s into the initialisers. The hooks now run with no inner hook calls. Root cause of the secondary panic. `use_unsaved_guard` installs a `beforeunload` closure that captures `dirty: ReadSignal<bool>` and calls `dirty.read()` when the browser fires the event. The listener stays installed across component teardown (wasm cannot detach a `Closure`-backed listener once a sibling component has already panicked), so the signal can be dropped by the time the event fires; `Signal::read` then panics with `ValueDroppedError`, which surfaces as the secondary trace QA captured. Fix: use `try_read` instead of `read` and treat a dropped signal as "not dirty" - no prompt, no panic. Acceptance criteria from MAPPS-299: - [x] "Schedule Appointment" opens the modal without crashing the wasm runtime (Calendar). - [x] Same path from Dispatch still works (no regression). - [x] Wasm-level panics still surface readable messages via `console_error_panic_hook` (PR #284, unchanged). - [x] Root cause documented in the commit body. #MAPPS-299