fix(Splunk Node): Retry attempts if no response from API call, better error with suggestion to use Retry On Fail (#9176)

Co-authored-by: Elias Meire <elias@meire.dev>
This commit is contained in:
Michael Kret 2024-04-24 11:05:53 +03:00 committed by GitHub
parent 2bf0a3933e
commit 05a569c1cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 189 additions and 21 deletions

View file

@ -6,7 +6,7 @@ import type {
IRequestOptions, IRequestOptions,
IHttpRequestMethods, IHttpRequestMethods,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow'; import { NodeApiError, NodeOperationError, sleep } from 'n8n-workflow';
import { parseString } from 'xml2js'; import { parseString } from 'xml2js';
@ -139,9 +139,29 @@ export async function splunkApiRequest(
delete options.qs; delete options.qs;
} }
let result;
try { try {
return await this.helpers.request(options).then(parseXml); let attempts = 0;
do {
try {
const response = await this.helpers.request(options);
result = await parseXml(response);
return result;
} catch (error) {
if (attempts >= 5) {
throw error;
}
await sleep(1000);
attempts++;
}
} while (true);
} catch (error) { } catch (error) {
if (result === undefined) {
throw new NodeOperationError(this.getNode(), 'No response from API call', {
description: "Try to use 'Retry On Fail' option from node's settings",
});
}
if (error?.cause?.code === 'ECONNREFUSED') { if (error?.cause?.code === 'ECONNREFUSED') {
throw new NodeApiError(this.getNode(), { ...(error as JsonObject), code: 401 }); throw new NodeApiError(this.getNode(), { ...(error as JsonObject), code: 401 });
} }

View file

@ -1,14 +1,16 @@
import type { import {
IExecuteFunctions, type IExecuteFunctions,
ICredentialsDecrypted, type ICredentialsDecrypted,
ICredentialTestFunctions, type ICredentialTestFunctions,
IDataObject, type IDataObject,
ILoadOptionsFunctions, type ILoadOptionsFunctions,
INodeCredentialTestResult, type INodeCredentialTestResult,
INodeExecutionData, type INodeExecutionData,
INodeType, type INodeType,
INodeTypeDescription, type INodeTypeDescription,
IRequestOptions, type IRequestOptions,
NodeApiError,
NodeOperationError,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
@ -35,6 +37,7 @@ import {
} from './descriptions'; } from './descriptions';
import type { SplunkCredentials, SplunkFeedResponse } from './types'; import type { SplunkCredentials, SplunkFeedResponse } from './types';
import set from 'lodash/set';
export class Splunk implements INodeType { export class Splunk implements INodeType {
description: INodeTypeDescription = { description: INodeTypeDescription = {
@ -155,7 +158,7 @@ export class Splunk implements INodeType {
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData(); const items = this.getInputData();
const returnData: IDataObject[] = []; const returnData: INodeExecutionData[] = [];
const resource = this.getNodeParameter('resource', 0); const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0); const operation = this.getNodeParameter('operation', 0);
@ -454,18 +457,30 @@ export class Splunk implements INodeType {
} }
} catch (error) { } catch (error) {
if (this.continueOnFail()) { if (this.continueOnFail()) {
returnData.push({ error: error.cause.error }); returnData.push({ json: { error: error.cause.error }, pairedItem: { item: i } });
continue; continue;
} }
throw error; if (error instanceof NodeApiError) {
set(error, 'context.itemIndex', i);
}
if (error instanceof NodeOperationError && error?.context?.itemIndex === undefined) {
set(error, 'context.itemIndex', i);
}
throw new NodeOperationError(this.getNode(), error, { itemIndex: i });
} }
Array.isArray(responseData) if (Array.isArray(responseData)) {
? returnData.push(...(responseData as IDataObject[])) for (const item of responseData) {
: returnData.push(responseData as IDataObject); returnData.push({ json: item, pairedItem: { item: i } });
}
} else {
returnData.push({ json: responseData, pairedItem: { item: i } });
}
} }
return [this.helpers.returnJsonArray(returnData)]; return [returnData];
} }
} }

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB