# Guide de Dépannage - Troubleshooting
Ce guide vous aide à résoudre les problèmes courants rencontrés avec la bibliothèque `objets_metier_rs`.
## Table des matières
- [Erreurs d'installation](#erreurs-dinstallation)
- [Erreurs de connexion](#erreurs-de-connexion)
- [Erreurs COM](#erreurs-com)
- [Erreurs de compilation](#erreurs-de-compilation)
- [Erreurs d'exécution](#erreurs-dexécution)
- [Problèmes de performance](#problèmes-de-performance)
- [Problèmes de données](#problèmes-de-données)
- [Diagnostic avancé](#diagnostic-avancé)
---
## Erreurs d'installation
### ❌ Erreur: "Classe non enregistrée" (0x80040154)
**Symptôme:**
```
Error: ComError { code: -2147221164, message: "Classe non enregistrée" }
```
**Cause:** La DLL `objets100c.dll` n'est pas enregistrée dans le registre Windows.
**Solution:**
1. Ouvrir PowerShell **en tant qu'administrateur**
2. Exécuter:
```powershell
regsvr32 "C:\Program Files\Sage\Sage 100c\objets100c.dll"
```
3. Vérifier le message de confirmation: "DllRegisterServer dans ... a réussi"
**Vérification:**
```powershell
# Vérifier que la DLL est bien là
Test-Path "C:\Program Files\Sage\Sage 100c\objets100c.dll"
```
**Note:** Le chemin exact peut varier selon votre installation. Chemins courants:
- `C:\Sage\Sage100c\objets100c.dll`
- `C:\Program Files (x86)\Sage\Sage 100c\objets100c.dll`
---
### ❌ Erreur: "Le module spécifié est introuvable"
**Symptôme:**
```
Error: Le module spécifié est introuvable
```
**Cause:** La DLL `objets100c.dll` n'existe pas au chemin spécifié.
**Solution:**
1. Rechercher la DLL:
```powershell
Get-ChildItem -Path "C:\" -Filter "objets100c.dll" -Recurse -ErrorAction SilentlyContinue
```
2. Une fois trouvée, enregistrer avec le bon chemin:
```powershell
regsvr32 "CHEMIN_REEL\objets100c.dll"
```
---
### ❌ Erreur: Compilation échoue avec "linking with `link.exe` failed"
**Symptôme:**
```
error: linking with `link.exe` failed: exit code: 1181
```
**Cause:** Build tools C++ manquants.
**Solution:**
Installer **Visual Studio Build Tools** :
1. Télécharger depuis https://visualstudio.microsoft.com/downloads/
2. Sélectionner "Développement Desktop en C++"
3. Installer et redémarrer
4. Relancer `cargo build`
---
## Erreurs de connexion
### ❌ Erreur: "Échec de l'ouverture de la base"
**Symptôme:**
```rust
Error: ComError { code: -1, message: "Échec de l'ouverture" }
```
**Causes possibles:**
#### 1. Chemin de base incorrect
**Solution:**
```rust
// ❌ Mauvais
app.set_name("D:\\Sage\\BIJOU.MAE")?; // Double backslash
// ✅ Bon
app.set_name(r"D:\Sage\BIJOU.MAE")?; // Raw string
```
**Vérification:**
```rust
use std::path::Path;
let db_path = r"D:\Sage\BIJOU.MAE";
if !Path::new(db_path).exists() {
eprintln!("❌ Base introuvable: {}", db_path);
}
```
#### 2. Base déjà ouverte
**Solution:**
```rust
// Fermer la base avant de la rouvrir
if app.is_open()? {
app.close()?;
}
app.open()?;
```
#### 3. Droits d'accès insuffisants
**Solution:**
- Vérifier les permissions NTFS sur le fichier `.MAE`
- Exécuter l'application en tant qu'administrateur
- Vérifier que la base n'est pas en lecture seule
---
### ❌ Erreur: "Authentification échouée"
**Symptôme:**
```rust
Error: ComError { message: "Authentification refusée" }
```
**Solutions:**
#### 1. Utilisateur incorrect
```rust
// ✅ Utilisateur Sage valide
loggable.set_user_name("<Administrateur>")?; // Avec les <>
loggable.set_user_password("")?;
// Ou autre utilisateur
loggable.set_user_name("COMPTABLE")?;
loggable.set_user_password("motdepasse")?;
```
#### 2. Vérifier l'utilisateur dans Sage
- Ouvrir Sage 100c en mode interface
- Fichier → Paramètres société → Utilisateurs
- Vérifier que l'utilisateur existe et a les droits
---
### ❌ Erreur: Base ouverte mais factories retournent des erreurs
**Symptôme:**
```rust
let factory = app.factory_journal()?;
// Error: Interface non supportée
```
**Cause:** Application non complètement initialisée.
**Solution:**
```rust
// Toujours vérifier l'état
if !app.is_open()? {
return Err(SageError::InternalError("Base non ouverte".into()));
}
// Utiliser les factories après ouverture complète
let factory = app.factory_journal()?;
```
---
## Erreurs COM
### ❌ Erreur: "Interface non supportée" (0x80004002)
**Symptôme:**
```
Error: ComError { code: -2147467262, message: "Interface non supportée" }
```
**Causes et solutions:**
#### 1. Mauvais CLSID
```rust
// ❌ CLSID incorrect
let app = CptaApplication::new("WRONG-CLSID")?;
// ✅ CLSID correct
let app = CptaApplication::new("309DE0FB-9FB8-4F4E-8295-CC60C60DAA33")?;
```
**CLSIDs officiels:**
- Comptabilité: `309DE0FB-9FB8-4F4E-8295-CC60C60DAA33`
- Commercial: `ED0EC116-16B8-44CC-A68A-41BF6E15EB3F`
#### 2. Version Sage incompatible
**Solution:**
Vérifier la version de Sage 100c (minimum v12 requis):
```powershell
Get-ItemProperty "C:\Program Files\Sage\Sage 100c\objets100c.dll" | Select-Object VersionInfo
```
---
### ❌ Erreur: "Accès refusé" (0x80070005)
**Symptôme:**
```
Error: ComError { code: -2147024891, message: "Accès refusé" }
```
**Solutions:**
1. **Exécuter en administrateur** (clic droit → "Exécuter en tant qu'administrateur")
2. **Vérifier les permissions COM:**
```powershell
dcomcnfg # Ouvrir la config DCOM
# Composants Services → Ordinateurs → Poste de travail → Config DCOM
```
3. **Désactiver UAC temporairement** (non recommandé en production)
---
### ❌ Erreur: "Serveur COM occupé" (0x8001010A)
**Symptôme:**
```
Error: ComError { code: -2147417846, message: "Le serveur COM est occupé" }
```
**Cause:** Appel COM concurrent ou timeout.
**Solutions:**
```rust
// 1. Ajouter des pauses entre appels
use std::thread;
use std::time::Duration;
for i in 0..100 {
let item = factory.read_numero(i)?;
// Traitement
if i % 10 == 0 {
thread::sleep(Duration::from_millis(50)); // Pause tous les 10
}
}
// 2. Utiliser des transactions pour grouper
let process = app.create_process_encoder()?;
// Ajouter toutes les lignes
process.process()?; // Une seule transaction
```
---
## Erreurs de compilation
### ❌ Erreur: "cannot find `objets_metier_rs` in the crate root"
**Symptôme:**
```
error[E0433]: failed to resolve: use of undeclared crate or module `objets_metier_rs`
```
**Solution:**
Vérifier `Cargo.toml`:
```toml
[dependencies]
objets_metier_rs = "1.0.0"
```
Puis:
```bash
cargo clean
cargo build
```
---
### ❌ Erreur: "trait bounds were not satisfied"
**Symptôme:**
```
error[E0277]: the trait bound `FactoryJournal: FactoryReadByCode<_>` is not satisfied
```
**Cause:** Utilisation d'un trait non implémenté par la factory.
**Solution:**
Vérifier les traits disponibles pour chaque factory:
```rust
// ❌ FactoryJournal n'implémente pas FactoryReadByCode
factory_journal.read_code("VTE")?; // ERREUR
// ✅ FactoryJournal implémente FactoryReadByNumero
factory_journal.read_numero(1)?; // OK
```
Consulter [TRAITS_GUIDE.md](TRAITS_GUIDE.md) pour la liste complète.
---
## Erreurs d'exécution
### ❌ Erreur: "Conversion VARIANT non implémentée"
**Symptôme:**
```rust
let value = dispatch.call_method_by_name("Name", &[])?;
println!("{}", value.to_string()?);
// Error: ConversionError("Type BSTR non supporté")
```
**Cause:** Type VARIANT non géré.
**Solution temporaire (v1.0.0):**
```rust
// Utiliser type_name() pour identifier le type
let value = dispatch.call_method_by_name("Name", &[])?;
println!("Type: {}", value.type_name());
// Les types de base sont supportés
let is_open: bool = app.is_open()?; // OK
let count: i32 = factory.count()?; // OK
```
---
### ❌ Erreur: "Cannot borrow as mutable"
**Symptôme:**
```rust
error[E0596]: cannot borrow `journal` as mutable
```
**Cause:** Objet non déclaré mutable.
**Solution:**
```rust
// ❌ Mauvais
let journal = factory.read_numero(1)?;
journal.set_jo_intitule("Nouveau")?; // ERREUR
// ✅ Bon
let mut journal = factory.read_numero(1)?;
journal.set_jo_intitule("Nouveau")?; // OK
journal.write()?;
```
---
### ❌ Panic: "called `Result::unwrap()` on an `Err` value"
**Symptôme:**
```
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ComError...'
```
**Cause:** Utilisation de `unwrap()` sans gestion d'erreur.
**Solution:**
```rust
// ❌ Mauvais - Panic si erreur
let journal = factory.read_numero(1).unwrap();
// ✅ Bon - Gestion explicite
let journal = match factory.read_numero(1) {
Ok(j) => j,
Err(e) => {
eprintln!("Erreur lecture journal: {}", e);
return Err(e);
}
};
// ✅ Encore mieux - Propagation
let journal = factory.read_numero(1)?;
```
---
### ❌ Erreur: "Déséquilibre Débit/Crédit"
**Symptôme:**
```rust
process.process()?;
// Error: "La pièce n'est pas équilibrée"
```
**Cause:** Somme Débits ≠ Somme Crédits.
**Solution:**
```rust
// Vérifier avant validation
println!("Débit total: {}", process.debit()?);
println!("Crédit total: {}", process.credit()?);
println!("Solde: {}", process.solde()?);
if process.solde()? != 0.0 {
// Équilibrer automatiquement
process.equilibrer()?;
}
// Vérifier la validation possible
if !process.can_process()? {
let errors = process.errors()?;
eprintln!("Erreurs de validation:");
for error in errors.list()? {
eprintln!(" - {}", error.message()?);
}
return Err(SageError::InternalError("Validation impossible".into()));
}
process.process()?;
```
---
## Problèmes de performance
### ⚠️ Lenteur: Liste de 10000 articles prend 30 secondes
**Diagnostic:**
```rust
use std::time::Instant;
let start = Instant::now();
let articles = factory.list()?; // Lent
println!("Durée: {:?}", start.elapsed());
```
**Solutions:**
#### 1. Utiliser `list_forward()` au lieu de `list()`
```rust
// ❌ Lent pour grandes collections
let articles = factory.list()?;
// ✅ Rapide avec curseur optimisé
let articles = factory.list_forward()?;
```
#### 2. Filtrer côté Sage avec `query_predicate()`
```rust
// ❌ Charge tout puis filtre en Rust
let tous = factory.list()?;
let actifs: Vec<_> = tous.into_iter()
.filter(|a| a.ar_sommeille().unwrap() == 0)
.collect();
// ✅ Filtre côté Sage (beaucoup plus rapide)
let actifs = factory.query_predicate("[AR_Sommeille] = 0")?;
```
#### 3. Utiliser le cache
```rust
use objets_metier_rs::cache::FactoryCache;
use std::time::Duration;
let cache = FactoryCache::new(Duration::from_secs(300));
// Premier appel: lent (lecture Sage)
let article = cached_read(&factory, &cache, "ART001")?;
// Appels suivants: rapide (depuis cache)
let article = cached_read(&factory, &cache, "ART001")?; // ~1ms
```
---
### ⚠️ Fuites mémoire: Usage RAM augmente continuellement
**Diagnostic:**
```rust
// Surveiller avec Task Manager ou:
use sysinfo::{System, SystemExt};
let mut sys = System::new_all();
sys.refresh_memory();
println!("Mémoire utilisée: {} MB", sys.used_memory() / 1024 / 1024);
```
**Solutions:**
#### 1. Libérer les objets COM explicitement
```rust
{
let app = CptaApplication::new("...")?;
app.open()?;
// Traitement
app.close()?;
// app est drop ici, libère COM
}
// Scope fermé = mémoire libérée
```
#### 2. Éviter de garder trop d'objets en mémoire
```rust
// ❌ Garde tout en mémoire
let mut journaux = Vec::new();
for i in 1..1000 {
journaux.push(factory.read_numero(i)?);
}
// ✅ Traite et libère
for i in 1..1000 {
let journal = factory.read_numero(i)?;
// Traiter journal
// journal est drop à la fin de l'itération
}
```
---
## Problèmes de données
### ❌ Erreur: "Doublon détecté sur la clé primaire"
**Symptôme:**
```rust
taxe.write()?;
// Error: "Une taxe avec le code 'TVA20' existe déjà"
```
**Solution:**
```rust
// Vérifier l'existence avant création
if factory_taxe.exist_code("TVA20")? {
println!("Taxe existe déjà, on la lit");
let mut taxe = factory_taxe.read_code("TVA20")?;
// Modifier
} else {
println!("Taxe n'existe pas, on la crée");
let mut taxe = factory_taxe.create()?;
taxe.set_ta_code("TVA20")?;
// Configurer et sauvegarder
}
```
---
### ❌ Erreur: "Référence invalide" lors de `set_compte_g()`
**Symptôme:**
```rust
ecriture.set_compte_g(&compte)?;
// Error: "Le compte n'existe pas"
```
**Solution:**
```rust
// Vérifier que le compte existe
let compte = match factory_compte.read_intitule("411000") {
Ok(c) => c,
Err(_) => {
eprintln!("Compte 411000 introuvable");
return Err(SageError::InternalError("Compte invalide".into()));
}
};
// Vérifier le type de compte
if compte.cg_type()? != 1 { // 1 = Détail
eprintln!("Le compte doit être de type Détail");
return Err(SageError::InternalError("Type compte invalide".into()));
}
ecriture.set_compte_g(&compte)?;
```
---
## Diagnostic avancé
### 🔍 Activer les logs détaillés
```rust
// Dans main()
env_logger::init();
// Ou avec niveau spécifique
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
```
Puis exécuter:
```bash
RUST_LOG=debug cargo run
```
---
### 🔍 Inspecter un objet COM
```rust
use objets_metier_rs::com::ComInstance;
let instance = ComInstance::new("309DE0FB-9FB8-4F4E-8295-CC60C60DAA33")?;
// Lister tous les membres
let members = instance.list_members()?;
for member in members {
println!("{}: {:?} (ID: {})", member.name, member.member_type, member.id);
}
// Lister seulement les méthodes
let methods = instance.list_methods_only()?;
println!("Méthodes disponibles: {}", methods.len());
// Lister seulement les propriétés
let properties = instance.list_properties()?;
println!("Propriétés disponibles: {}", properties.len());
```
---
### 🔍 Capturer les erreurs Sage détaillées
```rust
match app.open() {
Ok(_) => println!("✅ Ouverture réussie"),
Err(SageError::ComError { code, message }) => {
eprintln!("❌ Erreur COM:");
eprintln!(" Code: 0x{:X} ({})", code as u32, code);
eprintln!(" Message: {}", message);
// Codes courants
match code {
-2147221164 => eprintln!(" → Classe non enregistrée"),
-2147467262 => eprintln!(" → Interface non supportée"),
-2147024891 => eprintln!(" → Accès refusé"),
_ => eprintln!(" → Erreur inconnue"),
}
},
Err(e) => eprintln!("❌ Autre erreur: {}", e),
}
```
---
### 🔍 Benchmarking personnalisé
```rust
use std::time::Instant;
fn benchmark_operation<F>(name: &str, operation: F)
where
F: FnOnce() -> SageResult<()>
{
let start = Instant::now();
match operation() {
Ok(_) => {
let duration = start.elapsed();
println!("✅ {} - Durée: {:?}", name, duration);
},
Err(e) => {
println!("❌ {} - Erreur: {}", name, e);
}
}
}
// Utilisation
benchmark_operation("Liste journaux", || {
let journaux = factory.list()?;
println!(" Trouvés: {}", journaux.len());
Ok(())
});
```
---
## Obtenir de l'aide
Si ce guide ne résout pas votre problème:
1. **Vérifier les Issues GitHub** - Peut-être déjà signalé:
- https://github.com/your-repo/objets_metier_rs/issues
2. **Consulter la FAQ** - [FAQ.md](FAQ.md)
3. **Ouvrir une Issue** avec:
- Version de `objets_metier_rs` (`cargo tree | grep objets_metier_rs`)
- Version de Rust (`rustc --version`)
- Version de Sage 100c
- Code minimal reproduisant le problème
- Message d'erreur complet
- Stack trace si panic
4. **Discussions** pour questions générales:
- https://github.com/your-repo/objets_metier_rs/discussions
---
**Dernière mise à jour**: 2025-01-20 (v1.0.0)