From b6afc05148eed24d62dd79eda20b8782cbe8dc61 Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sun, 12 Apr 2026 02:41:58 +0200 Subject: [PATCH] fix: .cloud Oeffnen - besseres Error-Handling + Fallback-Dateiname - Dateiname: Erst aus JSON "name" Feld, Fallback: .cloud von Dateiname strippen - Alle Fehler werden jetzt gemeldet statt verschluckt (download, lock, open) - open::that Fehler wird zurueckgegeben statt ignoriert - Ausfuehrliches Logging: Pfade, Groesse, Lock-Status - Pruefung ob Download-Datei existiert bevor geoeffnet wird Co-Authored-By: Claude Opus 4.6 (1M context) --- clients/desktop/src-tauri/src/lib.rs | 60 +++++++++++++++++++++------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/clients/desktop/src-tauri/src/lib.rs b/clients/desktop/src-tauri/src/lib.rs index 96a2b09..118db57 100644 --- a/clients/desktop/src-tauri/src/lib.rs +++ b/clients/desktop/src-tauri/src/lib.rs @@ -230,36 +230,66 @@ async fn run_sync_now(state: State<'_, AppState>) -> Result, String> #[tauri::command] async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Result { - let engine = state.api.lock().unwrap().clone() - .ok_or("Nicht eingeloggt")?; + let api = state.api.lock().unwrap().clone() + .ok_or("Nicht eingeloggt - bitte zuerst anmelden")?; let path = PathBuf::from(&cloud_path); - let content = std::fs::read_to_string(&path).map_err(|e| e.to_string())?; - let placeholder: serde_json::Value = serde_json::from_str(&content).map_err(|e| e.to_string())?; - let file_id = placeholder.get("id").and_then(|v| v.as_i64()).ok_or("Keine ID")?; - let file_name = placeholder.get("name").and_then(|v| v.as_str()).unwrap_or("file"); + if !path.exists() { + return Err(format!("Datei nicht gefunden: {}", cloud_path)); + } - let real_path = path.parent().unwrap().join(file_name); + // Read placeholder JSON + let content = std::fs::read_to_string(&path) + .map_err(|e| format!("Platzhalter lesen: {}", e))?; + let placeholder: serde_json::Value = serde_json::from_str(&content) + .map_err(|e| format!("Platzhalter ungueltig: {}", e))?; + let file_id = placeholder.get("id").and_then(|v| v.as_i64()) + .ok_or("Keine Datei-ID im Platzhalter")?; - // Download - engine.download_file(file_id, &real_path).await?; + // Get real filename: from JSON "name" field, or strip .cloud from filename + let file_name = placeholder.get("name") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()) + .unwrap_or_else(|| { + let name = path.file_name().unwrap().to_string_lossy().to_string(); + name.strip_suffix(".cloud").unwrap_or(&name).to_string() + }); - // Remove placeholder + let real_path = path.parent().unwrap().join(&file_name); + eprintln!("[OpenCloud] {} -> {} (ID: {})", cloud_path, real_path.display(), file_id); + + // Download the actual file + api.download_file(file_id, &real_path).await + .map_err(|e| format!("Download fehlgeschlagen: {}", e))?; + + // Verify file was downloaded + if !real_path.exists() { + return Err(format!("Download fehlgeschlagen - Datei nicht vorhanden: {}", real_path.display())); + } + eprintln!("[OpenCloud] Downloaded {} bytes", std::fs::metadata(&real_path).map(|m| m.len()).unwrap_or(0)); + + // Remove .cloud placeholder std::fs::remove_file(&path).ok(); // Lock on server - let _ = engine.lock_file(file_id, "Desktop Sync Client").await; + let cloud_name = path.file_name().unwrap().to_string_lossy().to_string(); + match api.lock_file(file_id, "Desktop Sync Client").await { + Ok(_) => eprintln!("[OpenCloud] Locked file {}", file_id), + Err(e) => eprintln!("[OpenCloud] Lock failed (continuing): {}", e), + } state.locked_files.lock().unwrap().push(file_id); - // Track opened file for auto-close detection + // Track for auto-close detection state.opened_files.lock().unwrap().insert(file_id, OpenedFile { _file_id: file_id, real_path: real_path.clone(), - cloud_name: path.file_name().unwrap().to_string_lossy().to_string(), + cloud_name, }); - // Open with default application - let _ = open::that(&real_path); + // Open with default application for this file type + eprintln!("[OpenCloud] Opening with default app: {}", real_path.display()); + open::that(&real_path) + .map_err(|e| format!("Oeffnen fehlgeschlagen: {} - {}", real_path.display(), e))?; Ok(real_path.to_string_lossy().to_string()) }