Skip to content

fix: stop the voice alert panel crashing on its first alert (#1136) - #1141

Open
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1136-voice-alert-queue
Open

fix: stop the voice alert panel crashing on its first alert (#1136)#1141
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1136-voice-alert-queue

Conversation

@MOHITKOURAV01

Copy link
Copy Markdown
Contributor

Description

VoiceAlertManager renders its pending-alert list with queue.map(...), but queue was
never declared in that file and useVoiceSynthesis only ever returned queueLength. The
list sits behind a queueLength === 0 ? ... : ... guard, so the panel looked fine on load
and died the first time anything was queued:

ReferenceError: queue is not defined
    at VoiceAlertManager (src/components/VoiceAlertManager.jsx:209)

There is no error boundary around it, so the whole voice panel went blank on the very
action it exists for. ESLint has been reporting it as no-undef on this file the entire
time.


Related Issue

Closes #1136


Type of Change

  • Bug Fix
  • New Feature
  • Documentation
  • UI/UX Improvement
  • Refactoring
  • Performance Improvement
  • Accessibility

Changes Made

src/hooks/useVoiceSynthesis.js

  • Return queue alongside queueLength. That alone fixes the crash.

  • Insert by priority rather than appending. Both call sites tag their alert with a
    priority and one of them is explicitly CRITICAL, but addToQueue was
    setQueue(prev => [...prev, alert]) — a plain FIFO append that nothing read the priority
    in. A critical pollution alert waited behind however many routine messages were already
    queued, which is the wrong end of the queue for a feature meant to be listened to rather
    than watched.

    insertByPriority and priorityRank are exported and pure, so the ordering rules are
    testable without rendering. The item at index 0 is left alone while it is being spoken —
    moving it would leave the row the panel marks PLAYING pointing at a different alert.
    Interrupting speech already underway is clearQueue's job, not an insert's.

  • Put processQueue in its effect's dependency list. It closes over queue and config,
    and leaving it out was the react-hooks/exhaustive-deps warning on this file. A config
    change mid-queue now re-evaluates against the new config; isProcessingRef still stops
    the effect re-entering an utterance in flight.

  • Stop speech when alerts are switched off. Previously the toggle only declined to start
    the next message, so it appeared to do nothing until the current one finished.

  • Ignore an alert with no usable message, so a malformed payload cannot add a silent row
    that blocks the queue.

  • Don't setVoices after unmount — the voice list resolves asynchronously and can outlive
    the mount.

src/components/VoiceAlertManager.jsx

  • Destructure queue from the hook.
  • key={item.id ?? idx}, so an alert queued without an id doesn't collide.
  • aria-live="polite" on the pending count — this is the accessibility panel, and the
    queue depth changing is exactly the sort of thing a screen reader user should hear.

Tests (new)

  • src/hooks/useVoiceSynthesis.test.js — 21 tests: the full priorityRank table including
    case-insensitivity and unknown levels, insertByPriority ordering and immutability, and
    the hook's queue draining, priority ordering, disabled-mid-speech, clear, and
    failed-utterance-doesn't-wedge-the-queue behaviour.
  • src/components/VoiceAlertManager.test.jsx — 9 tests covering the empty state, the
    pending row that used to throw, the PLAYING marker, clearing, the unsupported-browser
    path, and the voice dropdown.

Testing

  • Tested locally
  • No console errors
  • Existing functionality works as expected
$ npx vitest run src/hooks/useVoiceSynthesis.test.js src/components/VoiceAlertManager.test.jsx
 ✓ src/hooks/useVoiceSynthesis.test.js (21 tests)
 ✓ src/components/VoiceAlertManager.test.jsx (9 tests)
 Test Files  2 passed (2)
      Tests  30 passed (30)

I checked the panel tests actually catch the bug rather than just passing: reverting the
two source files and re-running gives ReferenceError: queue is not defined on every one
of them.

npx eslint src/components/VoiceAlertManager.jsx src/hooks/useVoiceSynthesis.js no longer
reports the no-undef. The two remaining label-has-associated-control warnings on that
file are pre-existing and untouched here.

Note on CI

The Lint, Build and Playwright jobs are red on main and on every open PR right now
(3 parse errors in App.jsx, Leaderboard.jsx and NoisePollutionTracker.jsx — that's
#1129). Nothing in this branch touches those files.

…69#1136)

VoiceAlertManager renders the pending list with queue.map(...), but the hook
only ever returned queueLength. That branch is unreachable while the queue is
empty, so the panel looked fine until something was queued and then died with
ReferenceError: queue is not defined -- the no-undef ESLint has been reporting
on this file all along.

Return the queue alongside its length, and while the hook is open:

- Insert by priority instead of appending. Both call sites tag an alert with a
  priority and nothing read it, so a CRITICAL pollution alert waited behind
  every routine message already queued. insertByPriority leaves the head alone
  while it is mid-utterance, so the row marked PLAYING stays the row being
  spoken.
- Put processQueue in its effect's dependency list. It closes over queue and
  config, and omitting it was the exhaustive-deps warning here; isProcessingRef
  still stops re-entry into an utterance in flight.
- Stop speech when alerts are switched off, rather than letting the current
  message finish and making the toggle look inert.
- Drop alerts with no usable message, and don't set voices after unmount.

Tests: 21 for the hook and insertByPriority, 9 for the panel. The panel tests
fail with the original ReferenceError against the code before this change.
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

@MOHITKOURAV01 is attempting to deploy a commit to the Aditya Mahajan's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the ECSoC26 Contributions considered under ECSoC'26 label Aug 29, 2026
@github-actions

Copy link
Copy Markdown

Thank You for Your Contribution! 🎉

Hi @MOHITKOURAV01,

Thank you for opening this Pull Request and contributing to our project. We truly appreciate your efforts.

Please make sure that:

  • Your code follows the project's guidelines.
  • You have linked the appropriate issue (if applicable).
  • Screenshots are added for UI/UX changes.
  • Your PR is ready for review.

The maintainer @Aditya8369 will review your PR shortly!

Happy Contributing! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ECSoC26 Contributions considered under ECSoC'26

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VoiceAlertManager crashes with "ReferenceError: queue is not defined" as soon as any alert is queued, and CRITICAL alerts are spoken last

1 participant