
- API server with ChaCha20-Poly1305 encryption - TypeScript SDK client with full functionality - Complete documentation in docs/ - Environment variable processing with composite variables - HTTPS-only API on port 6666 - Storage structure for configuration files - Tests and examples included Features: - Quantum-resistant encryption (ChaCha20-Poly1305) - Variable substitution from .env files - Comprehensive TypeScript SDK - Full API documentation and specifications - Deployment guides and security model
241 lines
7.8 KiB
TypeScript
241 lines
7.8 KiB
TypeScript
/**
|
||
* 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<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 };
|