Skip to main content
Glama
ErrorHandlingValidator.ts5.92 kB
import WorkflowValidator from '../resources/WorkflowValidator.js'; /** * Validateur pour la gestion des erreurs dans les workflows n8n */ class ErrorHandlingValidator implements WorkflowValidator { /** * Valide la gestion des erreurs dans un workflow n8n * @param workflow Les données du workflow à valider * @param strictness Le niveau de rigueur de la validation * @returns Résultat de la validation avec les problèmes détectés */ validate(workflow: any, strictness: 'low' | 'medium' | 'high') { const issues: Array<{ message: string; recommendation: string; severity: 'low' | 'medium' | 'high'; location?: string; }> = []; // Vérifier si le workflow a une configuration globale de gestion d'erreurs if (!workflow.settings?.errorWorkflow) { issues.push({ message: 'Aucun workflow d\'erreur global n\'est configuré', recommendation: 'Configurez un workflow d\'erreur global pour gérer les échecs', severity: strictness === 'low' ? 'medium' : 'high', }); } // Vérifier les nœuds pour la gestion d'erreurs if (workflow.nodes && Array.isArray(workflow.nodes)) { // Identifier les nœuds HTTP, API ou d'intégration externe const externalNodes = workflow.nodes.filter((node: any) => { const type = (node.type || '').toLowerCase(); return type.includes('http') || type.includes('api') || type.includes('webhook') || type.includes('ftp') || type.includes('database') || type.includes('email'); }); // Vérifier si ces nœuds ont une gestion d'erreurs externalNodes.forEach((node: any) => { // Vérifier si le nœud a une configuration de gestion d'erreurs const hasErrorHandling = this.nodeHasErrorHandling(node, workflow); if (!hasErrorHandling) { issues.push({ message: `Le nœud "${node.name}" n'a pas de gestion d'erreurs`, recommendation: 'Ajoutez une gestion d\'erreurs pour ce nœud en utilisant des nœuds Error Trigger ou en configurant des chemins d\'erreur', severity: 'high', location: node.id, }); } }); // Vérifier les connexions entre les nœuds pour détecter les chemins d'erreur manquants if (workflow.connections && strictness !== 'low') { const nodesWithErrorOutputs = this.getNodesWithErrorOutputs(workflow); workflow.nodes.forEach((node: any) => { // Ignorer les nœuds de déclenchement (triggers) if ((node.type || '').toLowerCase().includes('trigger')) { return; } // Vérifier si le nœud a une sortie d'erreur configurée if (!nodesWithErrorOutputs.includes(node.id)) { issues.push({ message: `Le nœud "${node.name}" n'a pas de chemin d'erreur configuré`, recommendation: 'Ajoutez un chemin d\'erreur pour gérer les échecs potentiels', severity: strictness === 'medium' ? 'low' : 'medium', location: node.id, }); } }); } } // Vérifier si le workflow contient des nœuds spécifiques à la gestion d'erreurs const hasErrorHandlingNodes = this.workflowHasErrorHandlingNodes(workflow); if (!hasErrorHandlingNodes && strictness !== 'low') { issues.push({ message: 'Le workflow ne contient pas de nœuds dédiés à la gestion d\'erreurs', recommendation: 'Ajoutez des nœuds Error Trigger ou Error Catcher pour gérer les erreurs de manière centralisée', severity: 'medium', }); } return { valid: issues.length === 0, issues, }; } /** * Vérifie si un nœud a une gestion d'erreurs configurée */ private nodeHasErrorHandling(node: any, workflow: any): boolean { // Vérifier si le nœud a une configuration d'erreur spécifique if (node.continueOnFail === true) { return true; } // Vérifier si le nœud est connecté à un gestionnaire d'erreurs if (workflow.connections) { // Chercher des connexions sortantes depuis ce nœud vers un nœud de gestion d'erreurs const nodeConnections = workflow.connections[node.id]; if (nodeConnections) { // Vérifier les connexions de type "error" return Object.values(nodeConnections).some((connections: any) => { return connections.some((connection: any) => connection.type === 'error'); }); } } return false; } /** * Obtient la liste des IDs de nœuds qui ont des sorties d'erreur configurées */ private getNodesWithErrorOutputs(workflow: any): string[] { const nodesWithErrorOutputs: string[] = []; if (workflow.connections) { // Parcourir toutes les connexions pour trouver celles de type "error" Object.entries(workflow.connections).forEach(([sourceNodeId, connections]: [string, any]) => { Object.values(connections).forEach((targetConnections: any) => { if (targetConnections.some((connection: any) => connection.type === 'error')) { nodesWithErrorOutputs.push(sourceNodeId); } }); }); } return nodesWithErrorOutputs; } /** * Vérifie si le workflow contient des nœuds spécifiques à la gestion d'erreurs */ private workflowHasErrorHandlingNodes(workflow: any): boolean { if (!workflow.nodes || !Array.isArray(workflow.nodes)) { return false; } return workflow.nodes.some((node: any) => { const type = (node.type || '').toLowerCase(); return type.includes('error') || type.includes('catch') || type.includes('try') || type.includes('exception'); }); } } export default ErrorHandlingValidator;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lowprofix/n8n-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server