/** * Exemple de gestion d'erreurs avancée avec le SDK Vault 4NK * Démontre les différents types d'erreurs et leur gestion */ import { VaultClient, VaultApiError, VaultDecryptionError, VaultCrypto } from '../src/index'; async function errorHandlingExample() { console.log('🛡️ Exemple de gestion d\'erreurs - SDK Vault 4NK'); console.log('=' .repeat(55)); try { const client = new VaultClient( { baseUrl: 'https://vault.4nkweb.com:6666' }, 'quantum_resistant_demo_key_32_bytes!' ); // 1. Test des erreurs de connectivité console.log('🌐 Test des erreurs de connectivité...'); await testConnectivityErrors(client); // 2. Test des erreurs de fichiers console.log('\n📁 Test des erreurs de fichiers...'); await testFileErrors(client); // 3. Test des erreurs de déchiffrement console.log('\n🔐 Test des erreurs de déchiffrement...'); await testDecryptionErrors(); // 4. Test des erreurs de configuration console.log('\n⚙️ Test des erreurs de configuration...'); await testConfigurationErrors(); // 5. Gestion d'erreurs avec retry console.log('\n🔄 Test de retry automatique...'); await testRetryLogic(client); console.log('\n✅ Tous les tests de gestion d\'erreurs terminés!'); } catch (error) { console.error('❌ Erreur inattendue:', error); process.exit(1); } } async function testConnectivityErrors(client: VaultClient) { // Test avec une URL incorrecte const badClient = new VaultClient( { baseUrl: 'https://api-inexistante.example.com:6666' }, 'quantum_resistant_demo_key_32_bytes!' ); try { await badClient.health(); console.log(' ❌ Erreur: Devrait échouer'); } catch (error) { if (error instanceof VaultApiError) { console.log(` ✅ Erreur de connectivité capturée: ${error.message}`); } else { console.log(` ✅ Erreur réseau capturée: ${error instanceof Error ? error.message : error}`); } } // Test de timeout const timeoutClient = new VaultClient( { baseUrl: 'https://vault.4nkweb.com:6666', timeout: 1 }, // 1ms timeout 'quantum_resistant_demo_key_32_bytes!' ); try { await timeoutClient.health(); console.log(' ❌ Erreur: Devrait timeout'); } catch (error) { if (error instanceof VaultApiError && error.statusCode === 408) { console.log(` ✅ Timeout capturé: ${error.message}`); } else { console.log(` ✅ Erreur timeout: ${error instanceof Error ? error.message : error}`); } } } async function testFileErrors(client: VaultClient) { // Test avec un fichier inexistant try { await client.getFile('dev', 'fichier-inexistant.txt'); console.log(' ❌ Erreur: Fichier inexistant devrait échouer'); } catch (error) { if (error instanceof VaultApiError && error.statusCode === 404) { console.log(` ✅ Fichier inexistant: ${error.message}`); } else { console.log(` ✅ Erreur fichier: ${error instanceof Error ? error.message : error}`); } } // Test avec un environnement inexistant try { await client.getFile('prod', 'bitcoin/bitcoin.conf'); console.log(' ❌ Erreur: Environnement inexistant devrait échouer'); } catch (error) { if (error instanceof VaultApiError) { console.log(` ✅ Environnement inexistant: ${error.message} (${error.statusCode})`); } else { console.log(` ✅ Erreur environnement: ${error instanceof Error ? error.message : error}`); } } // Test avec un chemin invalide (tentative d'accès hors du répertoire) try { await client.getFile('dev', '../../../etc/passwd'); console.log(' ❌ Erreur: Chemin invalide devrait échouer'); } catch (error) { if (error instanceof VaultApiError && error.statusCode === 403) { console.log(` ✅ Chemin invalide (sécurité): ${error.message}`); } else { console.log(` ✅ Erreur sécurité: ${error instanceof Error ? error.message : error}`); } } } async function testDecryptionErrors() { // Test avec une clé de déchiffrement incorrecte const badKeyClient = new VaultClient( { baseUrl: 'https://vault.4nkweb.com:6666' }, 'clé-incorrecte-de-32-bytes!' // Clé différente ); try { await badKeyClient.getFile('dev', 'bitcoin/bitcoin.conf'); console.log(' ❌ Erreur: Clé incorrecte devrait échouer'); } catch (error) { if (error instanceof VaultDecryptionError) { console.log(` ✅ Erreur de déchiffrement: ${error.message}`); } else { console.log(` ✅ Erreur clé: ${error instanceof Error ? error.message : error}`); } } // Test avec une clé de taille incorrecte try { new VaultClient( { baseUrl: 'https://vault.4nkweb.com:6666' }, 'clé-trop-courte' // Moins de 32 bytes ); console.log(' ❌ Erreur: Clé trop courte devrait échouer'); } catch (error) { console.log(` ✅ Clé invalide: ${error instanceof Error ? error.message : error}`); } } async function testConfigurationErrors() { // Test avec une URL malformée try { new VaultClient( { baseUrl: 'url-malformée' }, 'quantum_resistant_demo_key_32_bytes!' ); console.log(' ❌ Erreur: URL malformée devrait échouer'); } catch (error) { console.log(` ✅ URL malformée: ${error instanceof Error ? error.message : error}`); } // Test avec un port invalide try { new VaultClient( { baseUrl: 'https://vault.4nkweb.com:99999' }, // Port invalide 'quantum_resistant_demo_key_32_bytes!' ); console.log(' ❌ Erreur: Port invalide devrait échouer'); } catch (error) { console.log(` ✅ Port invalide: ${error instanceof Error ? error.message : error}`); } } async function testRetryLogic(client: VaultClient) { // Implémentation d'un retry simple async function retryOperation( operation: () => Promise, maxRetries: number = 3, delay: number = 1000 ): Promise { let lastError: Error; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await operation(); } catch (error) { lastError = error as Error; console.log(` 🔄 Tentative ${attempt}/${maxRetries} échouée: ${lastError.message}`); if (attempt < maxRetries) { console.log(` ⏳ Attente de ${delay}ms avant retry...`); await new Promise(resolve => setTimeout(resolve, delay)); } } } throw lastError!; } // Test de retry avec une opération qui peut échouer try { const result = await retryOperation( () => client.getFile('dev', 'bitcoin/bitcoin.conf'), 3, 500 ); console.log(` ✅ Retry réussi: ${result.filename} (${result.size} chars)`); } catch (error) { console.log(` ❌ Retry échoué après toutes les tentatives: ${error instanceof Error ? error.message : error}`); } } // Fonction utilitaire pour logger les erreurs function logError(error: unknown, context: string) { console.log(`\n🚨 Erreur dans ${context}:`); if (error instanceof VaultApiError) { console.log(` Type: VaultApiError`); console.log(` Message: ${error.message}`); console.log(` Code: ${error.statusCode}`); console.log(` Endpoint: ${error.endpoint}`); } else if (error instanceof VaultDecryptionError) { console.log(` Type: VaultDecryptionError`); console.log(` Message: ${error.message}`); } else if (error instanceof Error) { console.log(` Type: ${error.constructor.name}`); console.log(` Message: ${error.message}`); console.log(` Stack: ${error.stack?.split('\n').slice(0, 3).join('\n')}`); } else { console.log(` Type: Inconnu`); console.log(` Valeur: ${error}`); } } // Exécution de l'exemple if (require.main === module) { errorHandlingExample(); } export { errorHandlingExample, logError };