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) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker
2026-04-12 02:41:58 +02:00
parent f71103185c
commit b6afc05148
+45 -15
View File
@@ -230,36 +230,66 @@ async fn run_sync_now(state: State<'_, AppState>) -> Result<Vec<String>, String>
#[tauri::command]
async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Result<String, String> {
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())
}