4NK_vault/sdk-client/examples/error-handling.ts
4NK Dev b13c8745e3 feat: Implémentation système sécurisé avec clés par utilisateur et environnement
-  API sécurisée avec authentification par ID utilisateur
-  HTTPS obligatoire avec rejet des connexions HTTP
-  Clés individuelles par utilisateur ET par environnement
-  Rotation automatique des clés avec sauvegarde de l'ancienne
-  Stockage sécurisé dans storage/<env>/_keys/
-  Client SDK mis à jour sans stockage de clés côté client
-  Documentation complète avec avertissements de sécurité
-  Tests complets du système sécurisé
- 🔒 Protection des fichiers sensibles dans .gitignore
2025-09-29 21:27:09 +00:00

241 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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' },
// Plus de clé de déchiffrement nécessaire - clés dynamiques utilisées
);
// 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' },
// Plus de clé de déchiffrement nécessaire - clés dynamiques utilisées
);
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
// Plus de clé de déchiffrement nécessaire - clés dynamiques utilisées
);
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<T>(
operation: () => Promise<T>,
maxRetries: number = 3,
delay: number = 1000
): Promise<T> {
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 };