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]
|
#[tauri::command]
|
||||||
async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Result<String, String> {
|
async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Result<String, String> {
|
||||||
let engine = state.api.lock().unwrap().clone()
|
let api = state.api.lock().unwrap().clone()
|
||||||
.ok_or("Nicht eingeloggt")?;
|
.ok_or("Nicht eingeloggt - bitte zuerst anmelden")?;
|
||||||
|
|
||||||
let path = PathBuf::from(&cloud_path);
|
let path = PathBuf::from(&cloud_path);
|
||||||
let content = std::fs::read_to_string(&path).map_err(|e| e.to_string())?;
|
if !path.exists() {
|
||||||
let placeholder: serde_json::Value = serde_json::from_str(&content).map_err(|e| e.to_string())?;
|
return Err(format!("Datei nicht gefunden: {}", cloud_path));
|
||||||
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");
|
|
||||||
|
|
||||||
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
|
// Get real filename: from JSON "name" field, or strip .cloud from filename
|
||||||
engine.download_file(file_id, &real_path).await?;
|
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();
|
std::fs::remove_file(&path).ok();
|
||||||
|
|
||||||
// Lock on server
|
// 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);
|
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 {
|
state.opened_files.lock().unwrap().insert(file_id, OpenedFile {
|
||||||
_file_id: file_id,
|
_file_id: file_id,
|
||||||
real_path: real_path.clone(),
|
real_path: real_path.clone(),
|
||||||
cloud_name: path.file_name().unwrap().to_string_lossy().to_string(),
|
cloud_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open with default application
|
// Open with default application for this file type
|
||||||
let _ = open::that(&real_path);
|
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())
|
Ok(real_path.to_string_lossy().to_string())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user