You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(sound-files): preserve uploads when ffmpeg conversion fails (#999)
The custom sound file upload pipeline could silently delete the user's
original file when ffmpeg failed mid-conversion, leaving an orphan DB row
that returned HTTP 422 on the Sound Files page. Defense-in-depth across
four layers:
- ConvertAudioFileAction: harden the unlink gate to require all requested
formats produced non-empty output, compare paths via realpath() with a
same-directory case-insensitive fallback, and emit a structured audit
trail through SystemMessages so post-incident forensics can identify
why the original was kept or removed.
- SoundFilesConf::convertAudioFile: write each target into a sibling
".converting" tempfile and rename() onto the destination only after
exit==0 && is_file && filesize>0. This eliminates the wav->wav in-place
corruption window and guarantees the source survives a partial failure.
- SoundFiles::afterDelete: add the missing 'opus' format to the cascade
cleanup list (drift since 7a9d11a) and sweep stray ".converting"
tempfiles left by interrupted workers.
- PlaybackAction: return HTTP 410 Gone (instead of the default 422) when
the audio file is missing or empty on disk, so the admin UI can render a
clear "Audio file missing on disk, please re-upload" badge instead of a
generic error. Frontend player marks the row, disables play, and reuses
the same 410 contract for both HEAD metadata probes and GET playback.
Also: regression tests for the unlink gate (with sentinel-stub ffmpeg to
prove PATH override actually intercepts Util::which), the atomic-rename
loop, and the cascade-delete sweep; new sf_AudioFileMissingWarning
translation across all 26 supported locales.
0 commit comments