From 5f905b49250fc7479dcceafedb7cd17ebe687e09 Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sun, 12 Apr 2026 10:25:01 +0200 Subject: [PATCH] fix: Sync-Fehler "error decoding response body" + Server-Edits Drei Probleme in einem: 1. create_folder/get_sync_tree parsten die Response auch bei HTTP- Fehlern als JSON. Bei 401/409/etc. kam "error decoding response body" statt der eigentlichen Fehlermeldung. Status wird jetzt zuerst geprueft, Body-Text wird bei Fehlern zurueckgegeben. 2. Ohne Journal-Eintrag und unterschiedlichen Hashes wurde vorher eine Konflikt-Kopie erstellt. Fuer Server-Edits aus dem Web-UI (wo der Client die Datei gar nie mit Journal erfasst hatte) war das falsch. Nextcloud-Ansatz: beim Erstkontakt Server autoritativ - Download statt Konflikt-Kopie. 3. run_sync_now uebernimmt neu konfigurierte sync_paths aus dem State, damit manuelle Syncs auch nach add_sync_path greifen. Co-Authored-By: Claude Opus 4.6 (1M context) --- clients/desktop/src-tauri/src/lib.rs | 2 ++ clients/desktop/src-tauri/src/sync/api.rs | 16 +++++++++++++--- clients/desktop/src-tauri/src/sync/engine.rs | 8 +++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/clients/desktop/src-tauri/src/lib.rs b/clients/desktop/src-tauri/src/lib.rs index 65e23d4..5af2e0c 100644 --- a/clients/desktop/src-tauri/src/lib.rs +++ b/clients/desktop/src-tauri/src/lib.rs @@ -244,6 +244,8 @@ async fn run_sync_now(state: State<'_, AppState>) -> Result, String> if let Some(ref api) = *state.api.lock().unwrap() { engine.api.access_token = api.access_token.clone(); } + // Refresh sync_paths from state: user may have added/removed paths + engine.sync_paths = state.sync_paths.lock().unwrap().clone(); let result = engine.sync_all().await; *state.sync_engine.lock().unwrap() = Some(engine); result diff --git a/clients/desktop/src-tauri/src/sync/api.rs b/clients/desktop/src-tauri/src/sync/api.rs index 5f0ff08..35f7a55 100644 --- a/clients/desktop/src-tauri/src/sync/api.rs +++ b/clients/desktop/src-tauri/src/sync/api.rs @@ -124,8 +124,13 @@ impl MiniCloudApi { .await .map_err(|e| format!("Sync-Tree Fehler: {}", e))?; + if !resp.status().is_success() { + let status = resp.status(); + let text = resp.text().await.unwrap_or_default(); + return Err(format!("Sync-Tree HTTP {}: {}", status, text)); + } let data: SyncTreeResponse = resp.json().await - .map_err(|e| format!("Parse-Fehler: {}", e))?; + .map_err(|e| format!("Sync-Tree Parse-Fehler: {}", e))?; Ok(data.tree) } @@ -204,9 +209,14 @@ impl MiniCloudApi { .json(&body) .send() .await - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Create-Folder Verbindungsfehler: {}", e))?; - resp.json().await.map_err(|e| e.to_string()) + if !resp.status().is_success() { + let status = resp.status(); + let text = resp.text().await.unwrap_or_default(); + return Err(format!("Create-Folder fehlgeschlagen ({}): {}", status, text)); + } + resp.json().await.map_err(|e| format!("Create-Folder Parse-Fehler: {}", e)) } pub async fn lock_file(&self, file_id: i64, client_info: &str) -> Result<(), String> { diff --git a/clients/desktop/src-tauri/src/sync/engine.rs b/clients/desktop/src-tauri/src/sync/engine.rs index b682aea..474b9f8 100644 --- a/clients/desktop/src-tauri/src/sync/engine.rs +++ b/clients/desktop/src-tauri/src/sync/engine.rs @@ -274,7 +274,13 @@ impl SyncEngine { let (local_changed, server_changed) = match &journal_entry { Some(j) => (local_hash != j.synced_checksum, server_hash != j.synced_checksum), - None => (true, true), // unknown history - treat as conflict to be safe + None => { + // No journal history: this is the first time we're tracking + // this file. Treat the server as authoritative (Nextcloud + // does the same on first sync) so edits made on the web + // GUI or other clients propagate down cleanly. + (false, true) + } }; if local_changed && !server_changed {