n8n-mcp
Version:
Integration between n8n workflow automation and Model Context Protocol (MCP)
340 lines ⢠12.9 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const workflow_validator_1 = require("../services/workflow-validator");
const node_repository_1 = require("../database/node-repository");
const database_adapter_1 = require("../database/database-adapter");
const enhanced_config_validator_1 = require("../services/enhanced-config-validator");
const logger_1 = require("../utils/logger");
const path_1 = __importDefault(require("path"));
const logger = new logger_1.Logger({ prefix: '[Test Error Handling]' });
const testWorkflows = [
{
name: 'Deprecated continueOnFail',
workflow: {
name: 'Test Deprecated Error Handling',
nodes: [
{
id: '1',
name: 'Webhook',
type: 'n8n-nodes-base.webhook',
position: [100, 100],
parameters: {
path: 'test-webhook',
httpMethod: 'POST'
},
continueOnFail: true
},
{
id: '2',
name: 'HTTP Request',
type: 'n8n-nodes-base.httpRequest',
position: [300, 100],
parameters: {
url: 'https://api.example.com/data',
method: 'GET'
},
continueOnFail: true
}
],
connections: {
'Webhook': {
main: [[{ node: 'HTTP Request', type: 'main', index: 0 }]]
}
}
}
},
{
name: 'Modern onError property',
workflow: {
name: 'Test Modern Error Handling',
nodes: [
{
id: '1',
name: 'Webhook',
type: 'n8n-nodes-base.webhook',
position: [100, 100],
parameters: {
path: 'test-webhook',
httpMethod: 'POST'
},
onError: 'continueRegularOutput',
alwaysOutputData: true
},
{
id: '2',
name: 'HTTP Request',
type: 'n8n-nodes-base.httpRequest',
position: [300, 100],
parameters: {
url: 'https://api.example.com/data',
method: 'POST',
sendBody: true,
contentType: 'json',
jsonBody: '{"test": "data"}'
},
onError: 'continueRegularOutput',
retryOnFail: true,
maxTries: 3,
waitBetweenTries: 2000,
alwaysOutputData: true
}
],
connections: {
'Webhook': {
main: [[{ node: 'HTTP Request', type: 'main', index: 0 }]]
}
}
}
},
{
name: 'Missing error handling',
workflow: {
name: 'Test Missing Error Handling',
nodes: [
{
id: '1',
name: 'Webhook',
type: 'n8n-nodes-base.webhook',
position: [100, 100],
parameters: {
path: 'test-webhook',
httpMethod: 'POST'
}
},
{
id: '2',
name: 'HTTP Request',
type: 'n8n-nodes-base.httpRequest',
position: [300, 100],
parameters: {
url: 'https://api.example.com/data',
method: 'GET'
}
},
{
id: '3',
name: 'Postgres',
type: 'n8n-nodes-base.postgres',
position: [500, 100],
parameters: {
operation: 'insert',
table: 'users',
columns: 'name,email'
}
}
],
connections: {
'Webhook': {
main: [[{ node: 'HTTP Request', type: 'main', index: 0 }]]
},
'HTTP Request': {
main: [[{ node: 'Postgres', type: 'main', index: 0 }]]
}
}
}
},
{
name: 'Mixed error handling',
workflow: {
name: 'Test Mixed Error Handling',
nodes: [
{
id: '1',
name: 'Manual Trigger',
type: 'n8n-nodes-base.manualTrigger',
position: [100, 100],
parameters: {}
},
{
id: '2',
name: 'OpenAI',
type: 'n8n-nodes-base.openAi',
position: [300, 100],
parameters: {
resource: 'chat',
operation: 'create',
model: 'gpt-3.5-turbo',
messages: {
values: [
{
role: 'user',
content: 'Hello'
}
]
}
},
onError: 'continueRegularOutput',
retryOnFail: true,
maxTries: 5,
waitBetweenTries: 5000
},
{
id: '3',
name: 'Slack',
type: 'n8n-nodes-base.slack',
position: [500, 100],
parameters: {
resource: 'message',
operation: 'post',
channel: '#general',
text: 'AI response: {{ $json.message }}'
},
continueOnFail: true
}
],
connections: {
'Manual Trigger': {
main: [[{ node: 'OpenAI', type: 'main', index: 0 }]]
},
'OpenAI': {
main: [[{ node: 'Slack', type: 'main', index: 0 }]]
}
}
}
},
{
name: 'Error output routing',
workflow: {
name: 'Test Error Output Routing',
nodes: [
{
id: '1',
name: 'Manual Trigger',
type: 'n8n-nodes-base.manualTrigger',
position: [100, 200],
parameters: {}
},
{
id: '2',
name: 'HTTP Request',
type: 'n8n-nodes-base.httpRequest',
position: [300, 200],
parameters: {
url: 'https://api.example.com/data',
method: 'GET'
},
onError: 'continueErrorOutput',
retryOnFail: true,
maxTries: 2,
alwaysOutputData: true
},
{
id: '3',
name: 'Success Handler',
type: 'n8n-nodes-base.set',
position: [500, 100],
parameters: {
mode: 'manual',
assignments: {
assignments: [
{
id: '1',
name: 'status',
value: 'success',
type: 'string'
}
]
}
}
},
{
id: '4',
name: 'Error Handler',
type: 'n8n-nodes-base.set',
position: [500, 300],
parameters: {
mode: 'manual',
assignments: {
assignments: [
{
id: '1',
name: 'status',
value: 'error',
type: 'string'
}
]
}
}
}
],
connections: {
'Manual Trigger': {
main: [[{ node: 'HTTP Request', type: 'main', index: 0 }]]
},
'HTTP Request': {
main: [[{ node: 'Success Handler', type: 'main', index: 0 }]],
error: [[{ node: 'Error Handler', type: 'main', index: 0 }]]
}
}
}
}
];
async function testErrorHandlingValidation() {
try {
const dbPath = path_1.default.join(process.cwd(), 'nodes.db');
const dbAdapter = await (0, database_adapter_1.createDatabaseAdapter)(dbPath);
const nodeRepository = new node_repository_1.NodeRepository(dbAdapter);
const validator = new workflow_validator_1.WorkflowValidator(nodeRepository, enhanced_config_validator_1.EnhancedConfigValidator);
logger.info('Testing error handling validation...\n');
for (const test of testWorkflows) {
logger.info(`\n${'='.repeat(80)}`);
logger.info(`Test: ${test.name}`);
logger.info('='.repeat(80));
const result = await validator.validateWorkflow(test.workflow, {
validateNodes: true,
validateConnections: true,
validateExpressions: false,
profile: 'strict'
});
logger.info(`\nValidation result: ${result.valid ? 'ā
VALID' : 'ā INVALID'}`);
if (result.errors.length > 0) {
logger.error('\nErrors:');
result.errors.forEach((error, index) => {
logger.error(` ${index + 1}. ${error.nodeName ? `[${error.nodeName}] ` : ''}${error.message}`);
if (error.details) {
logger.error(` Details: ${JSON.stringify(error.details)}`);
}
});
}
if (result.warnings.length > 0) {
logger.warn('\nWarnings:');
result.warnings.forEach((warning, index) => {
logger.warn(` ${index + 1}. ${warning.nodeName ? `[${warning.nodeName}] ` : ''}${warning.message}`);
});
}
if (result.suggestions.length > 0) {
logger.info('\nSuggestions:');
result.suggestions.forEach((suggestion, index) => {
logger.info(` ${index + 1}. ${suggestion}`);
});
}
const errorHandlingWarnings = result.warnings.filter((w) => w.message.includes('error handling') ||
w.message.includes('continueOnFail') ||
w.message.includes('onError'));
if (errorHandlingWarnings.length > 0) {
logger.info('\nš Error Handling Specific Issues:');
errorHandlingWarnings.forEach((warning) => {
logger.info(` - [${warning.nodeName}] ${warning.message}`);
});
}
logger.info('\nStatistics:');
logger.info(` Total nodes: ${result.statistics.totalNodes}`);
logger.info(` Enabled nodes: ${result.statistics.enabledNodes}`);
logger.info(` Valid connections: ${result.statistics.validConnections}`);
}
logger.info('\nā
Error handling validation tests completed!');
}
catch (error) {
logger.error('Test failed:', error);
process.exit(1);
}
}
testErrorHandlingValidation().catch(error => {
logger.error('Fatal error:', error);
process.exit(1);
});
//# sourceMappingURL=test-error-handling-validation.js.map