Fix 'Record all streams' joystick button intermittent failure#2715
Conversation
Automated PR Review (Claude)0. SummaryVerdict: MINOR SUGGESTIONS Minor items to consider: 1.1, 1.2, 6.1 This PR fixes an intermittent failure when using the joystick button to record all streams. The root cause was that 1. Correctness & Implementation Bugs1.1 (minor) —
This is an edge-case, and the 3 s throttle mitigates it for most users, but it could be addressed by making 1.2 (minor) — Multiple error dialogs when several streams time out. When 2. AGENTS.md AdherenceNo findings. The PR correctly:
3. Security3.1 No obfuscated or intentionally unreadable code. 3.2 No base64/hex/encoded blobs or binary-like strings. 3.3 No hidden Unicode, zero-width characters, or homoglyph attacks. 3.4 No unexpected network calls or exfiltration patterns. The change only adds a local polling loop using 3.5 No changes to build scripts, CI workflows, Dockerfiles, or Electron main-process code. 3.6 No changes to secret handling, CORS/CSP, 3.7 No new dependencies added. 3.8 No other suspicious patterns detected. No findings. 4. PerformanceNo findings. The polling loop ( 5. UI / UXNo findings beyond what is noted in 1.2 (potential dialog cascade, which was pre-existing behavior). 6. Code Quality & Style6.1 (nit) — Inconsistent use of In the diff, the "Media stream not defined" guard (diff context line ~35) is changed from 7. TestsNo findings. There are no existing unit tests for 8. DocumentationNo findings. The in-code JSDoc is updated appropriately with the new 9. Nitpicks / OptionalNo additional nitpicks beyond 6.1. Generated by Claude. This is advisory; a human reviewer must still approve. |
| * @returns {Promise<boolean>} True if the recording was successfully started, false if it was dropped (e.g. media stream never became ready) | ||
| */ | ||
| const startRecording = async (streamName: string): Promise<void> => { | ||
| const startRecording = async (streamName: string): Promise<boolean> => { |
There was a problem hiding this comment.
The startRecording function is an action and so it should succeed or fail. It it succeed, it should return early (undefined), as it was doing. If it fails it should throw.
Returning booleans on action functions is an anti-pattern from languages were throws didn't exist and one couldn't properly stack an error.
83f65e6 to
34b14ff
Compare
34b14ff to
f90564c
Compare
rafaellehmkuhl
left a comment
There was a problem hiding this comment.
|
@ArturoManzoli I'm planning to add this one to the v.1.18.3 patch release. |
…ached streams Signed-off-by: Arturo Manzoli <arturomanzoli@gmail.com>
f90564c to
1d2dd90
Compare
I'm not sure if the same problem that happens in your local machine is happening here. |

Primary issue was that
recordStream()would exit early if a WebRTC stream was not attached at the exact moment the "record all streams" button was pressed.Additionally,
startRecordingAllStreams()is an async function that was being called without an await (fire-and-forget). This caused it to incorrectly add dropped streams to streamsThatStarted and leave isRecordingAllStreams set to true.--
startRecording() now waits for the WebRTC mediaStream to be ready before proceeding, and then returns a boolean indicating success.
startRecordingAllStreams() now awaits the results for each stream, only counts the streams that successfully started, and reverts isRecordingAllStreams to false if none did.
Fix #2688