4NK_vault/sdk-client/examples/error-handling.ts
4NK Dev fcb15afb88 Initial commit: 4NK Vault API with quantum-resistant encryption
- 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
2025-09-29 21:02:18 +00:00

241 lines
7.8 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' },
'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 };