mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-22 12:19:09 +00:00
fix(Microsoft SQL Node): Handle connection errors correctly with continueOnFail (#15962)
This commit is contained in:
@@ -247,13 +247,24 @@ export class MicrosoftSql implements INodeType {
|
|||||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
const credentials = await this.getCredentials('microsoftSql');
|
const credentials = await this.getCredentials('microsoftSql');
|
||||||
|
|
||||||
const pool = configurePool(credentials);
|
|
||||||
await pool.connect();
|
|
||||||
|
|
||||||
let responseData: IDataObject | IDataObject[] = [];
|
let responseData: IDataObject | IDataObject[] = [];
|
||||||
let returnData: INodeExecutionData[] = [];
|
let returnData: INodeExecutionData[] = [];
|
||||||
|
|
||||||
const items = this.getInputData();
|
const items = this.getInputData();
|
||||||
|
const pairedItem = generatePairedItemData(items.length);
|
||||||
|
|
||||||
|
const pool = configurePool(credentials);
|
||||||
|
try {
|
||||||
|
await pool.connect();
|
||||||
|
} catch (error) {
|
||||||
|
void pool.close();
|
||||||
|
|
||||||
|
if (this.continueOnFail()) {
|
||||||
|
return [[{ json: { error: error.message }, pairedItem }]];
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const operation = this.getNodeParameter('operation', 0);
|
const operation = this.getNodeParameter('operation', 0);
|
||||||
const nodeVersion = this.getNode().typeVersion;
|
const nodeVersion = this.getNode().typeVersion;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import { mock } from 'jest-mock-extended';
|
||||||
|
import * as mssql from 'mssql';
|
||||||
|
import { constructExecutionMetaData, returnJsonArray } from 'n8n-core';
|
||||||
|
import type { IExecuteFunctions } from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { MicrosoftSql } from '../MicrosoftSql.node';
|
||||||
|
|
||||||
|
jest.mock('mssql');
|
||||||
|
|
||||||
|
function getMockedExecuteFunctions(overrides: Partial<IExecuteFunctions> = {}) {
|
||||||
|
return mock<IExecuteFunctions>({
|
||||||
|
getCredentials: jest.fn().mockResolvedValue({
|
||||||
|
server: 'localhost',
|
||||||
|
database: 'testdb',
|
||||||
|
user: 'testuser',
|
||||||
|
password: 'testpass',
|
||||||
|
port: 1433,
|
||||||
|
tls: false,
|
||||||
|
allowUnauthorizedCerts: true,
|
||||||
|
tdsVersion: '7_4',
|
||||||
|
connectTimeout: 1000,
|
||||||
|
requestTimeout: 10000,
|
||||||
|
}),
|
||||||
|
getInputData: jest.fn().mockReturnValue([{ json: {} }]),
|
||||||
|
getNode: jest.fn().mockReturnValue({ typeVersion: 1 }),
|
||||||
|
continueOnFail: jest.fn().mockReturnValue(true),
|
||||||
|
helpers: {
|
||||||
|
constructExecutionMetaData,
|
||||||
|
returnJsonArray,
|
||||||
|
},
|
||||||
|
evaluateExpression: jest.fn((_val) => _val),
|
||||||
|
...overrides,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('MicrosoftSql Node', () => {
|
||||||
|
let mockedConnectionPool: jest.MockedClass<typeof mssql.ConnectionPool>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockedConnectionPool = mssql.ConnectionPool as jest.MockedClass<typeof mssql.ConnectionPool>;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles connection error with continueOnFail', async () => {
|
||||||
|
const fakeError = new Error('Connection failed');
|
||||||
|
mockedConnectionPool.mockReturnValue(
|
||||||
|
mock<mssql.ConnectionPool>({
|
||||||
|
connect: jest.fn().mockRejectedValue(fakeError),
|
||||||
|
close: jest.fn(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const node = new MicrosoftSql();
|
||||||
|
const context = getMockedExecuteFunctions();
|
||||||
|
const result = await node.execute.call(context);
|
||||||
|
|
||||||
|
expect(result).toEqual([[{ json: { error: 'Connection failed' }, pairedItem: [{ item: 0 }] }]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('executes query on happy path', async () => {
|
||||||
|
const queryResult = { recordsets: [[{ value: 1 }]] };
|
||||||
|
const mockRequest = { query: jest.fn().mockResolvedValue(queryResult) };
|
||||||
|
const mockPool = mock<mssql.ConnectionPool>({
|
||||||
|
connect: jest.fn().mockResolvedValue(undefined),
|
||||||
|
close: jest.fn(),
|
||||||
|
request: jest.fn().mockReturnValue(mockRequest),
|
||||||
|
});
|
||||||
|
|
||||||
|
mockedConnectionPool.mockReturnValue(mockPool);
|
||||||
|
|
||||||
|
const node = new MicrosoftSql();
|
||||||
|
const context = getMockedExecuteFunctions({
|
||||||
|
getNodeParameter: jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValueOnce('executeQuery')
|
||||||
|
.mockReturnValueOnce('SELECT 1 AS value'),
|
||||||
|
});
|
||||||
|
const result = await node.execute.call(context);
|
||||||
|
|
||||||
|
expect(result).toEqual([[{ json: { value: 1 }, pairedItem: [{ item: 0 }] }]]);
|
||||||
|
expect(mockRequest.query).toHaveBeenCalledWith('SELECT 1 AS value');
|
||||||
|
expect(mockPool.close).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user