feat: add comprehensive error handling and logging for vault settings save operations with permission error detection and detailed error messages in UI toast notifications
This commit is contained in:
parent
2686cc5d11
commit
34f4e41419
137
TROUBLESHOOTING.md
Normal file
137
TROUBLESHOOTING.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# Dépannage ObsiGate
|
||||||
|
|
||||||
|
## Problème : Interface gèle lors de la sauvegarde des paramètres de fichiers cachés
|
||||||
|
|
||||||
|
### Symptômes
|
||||||
|
- L'interface se fige quand vous cliquez sur "Sauvegarder" dans la section "Fichiers cachés"
|
||||||
|
- Le fichier `vault_settings.json` n'est pas créé dans `/DOCKER_CONFIG/ObsiGate/data`
|
||||||
|
- Aucun message d'erreur n'apparaît (ou message générique)
|
||||||
|
|
||||||
|
### Cause
|
||||||
|
Le conteneur Docker n'a pas les permissions nécessaires pour écrire dans le répertoire `/app/data` (monté depuis `/DOCKER_CONFIG/ObsiGate/data` sur l'hôte).
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
|
||||||
|
#### 1. Vérifier que le répertoire existe sur l'hôte
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer le répertoire s'il n'existe pas
|
||||||
|
sudo mkdir -p /DOCKER_CONFIG/ObsiGate/data
|
||||||
|
|
||||||
|
# Vérifier qu'il existe
|
||||||
|
ls -la /DOCKER_CONFIG/ObsiGate/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Corriger les permissions
|
||||||
|
|
||||||
|
Le conteneur s'exécute avec l'utilisateur `1000:1000` (voir `docker-compose.yml`). Le répertoire doit être accessible en écriture par cet utilisateur.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option A: Donner la propriété à l'utilisateur 1000
|
||||||
|
sudo chown -R 1000:1000 /DOCKER_CONFIG/ObsiGate/data
|
||||||
|
|
||||||
|
# Option B: Rendre le répertoire accessible en écriture pour tous (moins sécurisé)
|
||||||
|
sudo chmod -R 777 /DOCKER_CONFIG/ObsiGate/data
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Redémarrer le conteneur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/ObsiGate
|
||||||
|
docker-compose restart
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Vérifier les logs
|
||||||
|
|
||||||
|
Après le redémarrage, les logs backend afficheront des informations détaillées sur la sauvegarde :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose logs -f obsigate
|
||||||
|
```
|
||||||
|
|
||||||
|
Recherchez des lignes comme :
|
||||||
|
- `Attempting to save settings to /app/data/vault_settings.json`
|
||||||
|
- `Successfully saved settings for X vaults`
|
||||||
|
- Ou des erreurs : `Permission denied writing to...`
|
||||||
|
|
||||||
|
#### 5. Tester la sauvegarde
|
||||||
|
|
||||||
|
1. Ouvrez l'interface ObsiGate
|
||||||
|
2. Allez dans Configuration → Fichiers cachés
|
||||||
|
3. Modifiez un paramètre (cochez/décochez "Afficher tous les fichiers cachés")
|
||||||
|
4. Cliquez sur "💾 Sauvegarder"
|
||||||
|
5. Vous devriez voir un message de succès : "✓ Paramètres sauvegardés"
|
||||||
|
6. Si erreur, le message affichera maintenant le détail : "Erreur: Permission denied: Cannot write to settings file..."
|
||||||
|
|
||||||
|
#### 6. Vérifier que le fichier a été créé
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -la /DOCKER_CONFIG/ObsiGate/data/vault_settings.json
|
||||||
|
cat /DOCKER_CONFIG/ObsiGate/data/vault_settings.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Le fichier devrait contenir un JSON avec vos paramètres :
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Workout": {
|
||||||
|
"includeHidden": true,
|
||||||
|
"hiddenWhitelist": []
|
||||||
|
},
|
||||||
|
"Bruno": {
|
||||||
|
"includeHidden": false,
|
||||||
|
"hiddenWhitelist": [".obsidian"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vérification des permissions actuelles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Voir les permissions du répertoire
|
||||||
|
ls -la /DOCKER_CONFIG/ObsiGate/
|
||||||
|
|
||||||
|
# Voir l'utilisateur qui exécute le conteneur
|
||||||
|
docker-compose exec obsigate id
|
||||||
|
|
||||||
|
# Devrait afficher : uid=1000 gid=1000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alternative : Changer l'utilisateur du conteneur
|
||||||
|
|
||||||
|
Si vous ne pouvez pas modifier les permissions de `/DOCKER_CONFIG/ObsiGate/data`, vous pouvez changer l'utilisateur du conteneur dans `docker-compose.yml` :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
obsigate:
|
||||||
|
# Remplacer user: "1000:1000" par l'UID/GID du propriétaire du répertoire
|
||||||
|
user: "0:0" # root (non recommandé pour la sécurité)
|
||||||
|
# OU
|
||||||
|
user: "$(id -u):$(id -g)" # Votre utilisateur actuel
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis redémarrez :
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Autres problèmes courants
|
||||||
|
|
||||||
|
### Les fichiers cachés ne s'affichent pas après sauvegarde
|
||||||
|
|
||||||
|
**Cause** : Les paramètres sont sauvegardés mais l'index n'a pas été reconstruit.
|
||||||
|
|
||||||
|
**Solution** : Après avoir cliqué sur "Sauvegarder", cliquez sur "🔄 Réindexer" pour reconstruire l'index avec les nouveaux paramètres.
|
||||||
|
|
||||||
|
### L'interface se fige lors de la réindexation
|
||||||
|
|
||||||
|
**Cause** : Vous essayez d'indexer un très gros répertoire caché (ex: `.git`, `.node_modules`).
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
1. N'activez pas "Afficher tous les fichiers cachés" pour les vaults contenant de gros répertoires cachés
|
||||||
|
2. Utilisez plutôt la liste blanche pour ajouter uniquement les dossiers cachés spécifiques dont vous avez besoin (ex: `.obsidian`)
|
||||||
|
3. La réindexation sélective (uniquement les vaults modifiés) devrait être plus rapide
|
||||||
|
|
||||||
|
### Message "Permission denied" dans les logs
|
||||||
|
|
||||||
|
Voir la section principale ci-dessus pour corriger les permissions.
|
||||||
@ -1477,7 +1477,20 @@ async def api_update_vault_settings(vault_name: str, body: dict = Body(...), cur
|
|||||||
settings_to_update["hiddenWhitelist"] = body["hiddenWhitelist"]
|
settings_to_update["hiddenWhitelist"] = body["hiddenWhitelist"]
|
||||||
|
|
||||||
# Update persisted settings
|
# Update persisted settings
|
||||||
|
try:
|
||||||
updated = update_vault_setting(vault_name, settings_to_update)
|
updated = update_vault_setting(vault_name, settings_to_update)
|
||||||
|
except PermissionError as e:
|
||||||
|
logger.error(f"Permission error saving settings for vault '{vault_name}': {e}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail=f"Permission denied: Cannot write to settings file. Check /app/data permissions."
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error saving settings for vault '{vault_name}': {e}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail=f"Failed to save settings: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
# Update in-memory vault config
|
# Update in-memory vault config
|
||||||
if vault_name in vault_config:
|
if vault_name in vault_config:
|
||||||
|
|||||||
@ -46,14 +46,27 @@ def save_vault_settings() -> None:
|
|||||||
"""Persist vault settings to disk."""
|
"""Persist vault settings to disk."""
|
||||||
with _settings_lock:
|
with _settings_lock:
|
||||||
try:
|
try:
|
||||||
|
logger.info(f"Attempting to save settings to {_SETTINGS_PATH}")
|
||||||
|
logger.info(f"Parent directory: {_SETTINGS_PATH.parent}")
|
||||||
|
logger.info(f"Parent exists: {_SETTINGS_PATH.parent.exists()}")
|
||||||
|
|
||||||
_SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
|
_SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||||
_SETTINGS_PATH.write_text(
|
logger.info(f"Directory created/verified: {_SETTINGS_PATH.parent}")
|
||||||
json.dumps(_vault_settings, indent=2, ensure_ascii=False),
|
|
||||||
encoding="utf-8"
|
content = json.dumps(_vault_settings, indent=2, ensure_ascii=False)
|
||||||
)
|
logger.info(f"JSON content prepared ({len(content)} bytes)")
|
||||||
logger.info(f"Saved settings for {len(_vault_settings)} vaults")
|
|
||||||
|
_SETTINGS_PATH.write_text(content, encoding="utf-8")
|
||||||
|
logger.info(f"Successfully saved settings for {len(_vault_settings)} vaults to {_SETTINGS_PATH}")
|
||||||
|
except PermissionError as e:
|
||||||
|
logger.error(f"Permission denied writing to {_SETTINGS_PATH}: {e}")
|
||||||
|
logger.error(f"Check that user has write permissions to {_SETTINGS_PATH.parent}")
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to save vault settings: {e}")
|
logger.error(f"Failed to save vault settings to {_SETTINGS_PATH}: {e}")
|
||||||
|
logger.error(f"Error type: {type(e).__name__}")
|
||||||
|
import traceback
|
||||||
|
logger.error(f"Traceback: {traceback.format_exc()}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3456,6 +3456,12 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(settings)
|
body: JSON.stringify(settings)
|
||||||
|
}).then(async response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||||
|
throw new Error(errorData.detail || `HTTP ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -3466,7 +3472,8 @@
|
|||||||
showToast("✓ Paramètres sauvegardés", "success");
|
showToast("✓ Paramètres sauvegardés", "success");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to save hidden files settings:", err);
|
console.error("Failed to save hidden files settings:", err);
|
||||||
showToast("Erreur de sauvegarde", "error");
|
const errorMsg = err.message || "Erreur inconnue";
|
||||||
|
showToast(`Erreur: ${errorMsg}`, "error");
|
||||||
} finally {
|
} finally {
|
||||||
if (btn) { btn.disabled = false; btn.textContent = "💾 Sauvegarder"; }
|
if (btn) { btn.disabled = false; btn.textContent = "💾 Sauvegarder"; }
|
||||||
}
|
}
|
||||||
@ -3501,7 +3508,8 @@
|
|||||||
await Promise.all([loadVaults(), loadTags()]);
|
await Promise.all([loadVaults(), loadTags()]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Reindex with hidden files error:", err);
|
console.error("Reindex with hidden files error:", err);
|
||||||
showToast("Erreur de réindexation", "error");
|
const errorMsg = err.message || "Erreur inconnue";
|
||||||
|
showToast(`Erreur: ${errorMsg}`, "error");
|
||||||
} finally {
|
} finally {
|
||||||
if (btn) { btn.disabled = false; btn.textContent = "🔄 Réindexer"; }
|
if (btn) { btn.disabled = false; btn.textContent = "🔄 Réindexer"; }
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user