mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(dictation): stop dictation before edit-save, remove expect() in openai_client
- Stop active dictation run before the edit branch clears/saves, matching the normal-send path. Prevents late transcript events from writing back into the restored or fresh draft after an edit save. - Replace .expect() in openai_client() with proper error propagation via Result, avoiding a panic if TLS backend initialization ever fails. Addresses review feedback on PR #1511.
This commit is contained in:
@@ -91,7 +91,9 @@ pub async fn create_transcribe_session(
|
||||
|
||||
let model = state.config.transcription_model.clone();
|
||||
|
||||
let response = openai_client()
|
||||
let client = openai_client().map_err(|(status, msg)| api_error(status, msg))?;
|
||||
|
||||
let response = client
|
||||
.post(OPENAI_REALTIME_CLIENT_SECRETS_URL)
|
||||
.header("Authorization", format!("Bearer {api_key}"))
|
||||
.header("Content-Type", "application/json")
|
||||
@@ -220,14 +222,25 @@ fn transcribe_rate_limited(state: &AppState, community: CommunityId, pubkey: &no
|
||||
}
|
||||
|
||||
/// Shared HTTP client for OpenAI requests (connection pooling).
|
||||
fn openai_client() -> &'static reqwest::Client {
|
||||
fn openai_client() -> Result<&'static reqwest::Client, (StatusCode, &'static str)> {
|
||||
static CLIENT: std::sync::OnceLock<reqwest::Client> = std::sync::OnceLock::new();
|
||||
CLIENT.get_or_init(|| {
|
||||
reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build()
|
||||
.expect("failed to build reqwest client")
|
||||
})
|
||||
// `get_or_init` only runs the closure once; if TLS backend init fails we
|
||||
// propagate an API error instead of panicking in production.
|
||||
if let Some(c) = CLIENT.get() {
|
||||
return Ok(c);
|
||||
}
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build()
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"failed to initialize HTTP client",
|
||||
)
|
||||
})?;
|
||||
// Another thread may have raced us — `get_or_init` is fine here since we
|
||||
// already proved construction succeeds.
|
||||
Ok(CLIENT.get_or_init(|| client))
|
||||
}
|
||||
|
||||
fn extract_client_secret(value: &Value) -> Option<String> {
|
||||
|
||||
@@ -558,6 +558,7 @@ function MessageComposerImpl({
|
||||
// Edit mode
|
||||
if (editTargetRef.current && onEditSaveRef.current) {
|
||||
if (isSendingRef.current || isUploadingRef.current) return;
|
||||
stopDictationRef.current(); // stop dictation so late transcripts don't refill during edit save
|
||||
const currentPendingImeta = media.pendingImetaRef.current;
|
||||
const hasMedia = currentPendingImeta.length > 0;
|
||||
// Empty text + zero attachments is a no-op (don't let edit become an
|
||||
|
||||
Reference in New Issue
Block a user