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:
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user