From eb04104bcb47db2613f4e572cbcd641787f0ff64 Mon Sep 17 00:00:00 2001 From: Beingpax Date: Fri, 12 Dec 2025 20:31:41 +0545 Subject: [PATCH] Record failure notifications --- VoiceInk/AudioEngineRecorder.swift | 21 +++++++++++++++++++++ VoiceInk/Recorder.swift | 22 ++++++++++++++++++++++ VoiceInk/Views/MenuBarView.swift | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/VoiceInk/AudioEngineRecorder.swift b/VoiceInk/AudioEngineRecorder.swift index 7ca0009..d3f596b 100644 --- a/VoiceInk/AudioEngineRecorder.swift +++ b/VoiceInk/AudioEngineRecorder.swift @@ -26,6 +26,9 @@ class AudioEngineRecorder: ObservableObject { private let audioProcessingQueue = DispatchQueue(label: "com.prakashjoshipax.VoiceInk.audioProcessing", qos: .userInitiated) private let fileWriteLock = NSLock() + // Callback to notify parent class of runtime recording errors + var onRecordingError: ((Error) -> Void)? + init() { setupNotifications() } @@ -225,6 +228,9 @@ class AudioEngineRecorder: ObservableObject { guard let convertedBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: outputCapacity) else { logger.error("Failed to create converted buffer") + Task { @MainActor in + self.onRecordingError?(AudioEngineRecorderError.bufferConversionFailed) + } return } @@ -244,6 +250,9 @@ class AudioEngineRecorder: ObservableObject { if let error = error { logger.error("Audio conversion error: \(error.localizedDescription)") + Task { @MainActor in + self.onRecordingError?(AudioEngineRecorderError.audioConversionError(error)) + } return } @@ -251,6 +260,9 @@ class AudioEngineRecorder: ObservableObject { try audioFile.write(from: convertedBuffer) } catch { logger.error("Failed to write buffer to file: \(error.localizedDescription)") + Task { @MainActor in + self.onRecordingError?(AudioEngineRecorderError.fileWriteFailed(error)) + } } } @@ -309,6 +321,9 @@ enum AudioEngineRecorderError: LocalizedError { case failedToCreateFile(Error) case failedToCreateConverter case failedToStartEngine(Error) + case bufferConversionFailed + case audioConversionError(Error) + case fileWriteFailed(Error) var errorDescription: String? { switch self { @@ -322,6 +337,12 @@ enum AudioEngineRecorderError: LocalizedError { return "Failed to create audio format converter" case .failedToStartEngine(let error): return "Failed to start audio engine: \(error.localizedDescription)" + case .bufferConversionFailed: + return "Failed to create buffer for audio conversion" + case .audioConversionError(let error): + return "Audio format conversion failed: \(error.localizedDescription)" + case .fileWriteFailed(let error): + return "Failed to write audio data to file: \(error.localizedDescription)" } } } \ No newline at end of file diff --git a/VoiceInk/Recorder.swift b/VoiceInk/Recorder.swift index 4c7f9ff..15c5dde 100644 --- a/VoiceInk/Recorder.swift +++ b/VoiceInk/Recorder.swift @@ -90,6 +90,13 @@ class Recorder: NSObject, ObservableObject { let engineRecorder = AudioEngineRecorder() recorder = engineRecorder + // Set up error callback to handle runtime recording failures + engineRecorder.onRecordingError = { [weak self] error in + Task { @MainActor in + await self?.handleRecordingError(error) + } + } + try engineRecorder.startRecording(toOutputFile: url) logger.info("✅ AudioEngineRecorder started successfully") @@ -153,6 +160,21 @@ class Recorder: NSObject, ObservableObject { deviceManager.isRecordingActive = false } + private func handleRecordingError(_ error: Error) async { + logger.error("❌ Recording error occurred: \(error.localizedDescription)") + + // Stop the recording + stopRecording() + + // Notify the user about the recording failure + await MainActor.run { + NotificationManager.shared.showNotification( + title: "Recording Failed: \(error.localizedDescription)", + type: .error + ) + } + } + private func updateAudioMeter() { guard let recorder = recorder else { return } diff --git a/VoiceInk/Views/MenuBarView.swift b/VoiceInk/Views/MenuBarView.swift index 61f826f..6250716 100644 --- a/VoiceInk/Views/MenuBarView.swift +++ b/VoiceInk/Views/MenuBarView.swift @@ -224,7 +224,7 @@ struct MenuBarView: View { } Divider() - + Button("Quit VoiceInk") { NSApplication.shared.terminate(nil) }