recording->refresh(); $this->recording->forceFill([ 'transcription_status' => 'processing', 'transcription_started_at' => $this->recording->transcription_started_at ?? now(), 'transcription_error' => null, ])->save(); $this->recording->reportProgress('Preparing audio file…', 15); try { $text = $transcription->transcribe( $this->recording, fn (string $message, int $percent) => $this->recording->reportProgress($message, $percent), ); $this->recording->reportProgress('Saving transcript…', 90); $this->recording->forceFill([ 'transcript' => $text, 'transcription_status' => 'done', 'transcription_progress' => 'Transcription complete', 'transcription_percent' => 100, 'transcription_error' => null, 'transcribed_at' => now(), ])->save(); } catch (Throwable $e) { Log::error('Transcription failed', [ 'recording_id' => $this->recording->id, 'driver' => $this->recording->transcription_driver, 'message' => $e->getMessage(), ]); $this->recording->forceFill([ 'transcription_status' => 'failed', 'transcription_progress' => 'Transcription failed', 'transcription_percent' => $this->recording->transcription_percent ?: 0, 'transcription_error' => $e->getMessage(), ])->save(); throw $e; } } /** * Handle a job failure (timeouts, worker kill, etc.). */ public function failed(?Throwable $e): void { $this->recording->forceFill([ 'transcription_status' => 'failed', 'transcription_progress' => 'Transcription failed', 'transcription_error' => $e?->getMessage() ?: 'Transcription stopped unexpectedly.', ])->save(); } }