Skip to content

Fix error handling in realtime session export#149

Open
ruccho wants to merge 1 commit into
mainfrom
fix/mux-export-error-handling
Open

Fix error handling in realtime session export#149
ruccho wants to merge 1 commit into
mainfrom
fix/mux-export-error-handling

Conversation

@ruccho

@ruccho ruccho commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

RealtimeInstantReplaySession had two error-handling defects in its export path.

1. MuxSegmentAsync — disposes the muxer while the video task is still running on audio failure
The code awaits in the order var video = MuxVideoAsync(); var audio = MuxAudioAsync(); await audio; await video;. If await audio throws, the video ValueTask is left unobserved while using var muxer is disposed. The still-running MuxVideoAsync then issues PushVideoDataAsync / FinishVideoAsync on the disposed native muxer (worst case a native crash), and the exception is left unobserved.

2. StopAndExportAsync — State left in a half-finished value on pipeline-completion failure
The Task.WhenAll(...CompleteAsync...) was outside the try/catch that sets State = Invalid. If it throws, State stays at WaitForRecordingComplete, leaving the session in a half-finished state.

Fix

  1. Convert MuxVideoAsync() / MuxAudioAsync() to Tasks via .AsTask() and await Task.WhenAll. Even if one fails, both complete before the muxer is disposed. If both fail, all exceptions propagate via AggregateException; a single failure propagates the original exception type as before (backward compatible).
  2. Move the pipeline-completion wait inside the existing try block so a throw there also transitions State = Invalid.

Out of scope: the broader concurrency guard between Dispose and export (a larger state-machine change) is not addressed here.

Verification

Unity Play Mode: ~183s record → export completed with zero errors (confirmed no regression on the normal export path). The error-path changes are covered by static review.

🤖 Generated with Claude Code

- await both video and audio mux tasks even if one fails, so the muxer
  is not disposed while the other task is still pushing data to it;
  propagate all failures via AggregateException when both tasks fail
- move pipeline completion wait inside try block so the session state
  transitions to Invalid when waiting for recording completion fails

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ruccho ruccho marked this pull request as ready for review July 3, 2026 04:40
@ruccho ruccho requested a review from hkmt-mmy July 3, 2026 04:40
var video = MuxVideoAsync().AsTask();
var audio = MuxAudioAsync().AsTask();

var whenAll = Task.WhenAll(video, audio);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

212行目ではWhenAll内でAsTaskしているのに、こちらは外でAsTaskしているのには何か理由がある?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants