n8n-nodes-arubacentral
Version:
n8n community node for Aruba Central API integration with comprehensive monitoring, configuration, and management capabilities
159 lines (137 loc) • 4.93 kB
text/typescript
// helpers/errorHandler.ts
import {
IExecuteFunctions,
NodeApiError,
NodeOperationError,
INodeExecutionData,
} from 'n8n-workflow';
import { logger } from './logger';
/**
* Handle API errors from Aruba Central
*
* @param this The n8n execution context
* @param error The error that was caught
* @param message Optional custom error message
* @returns Never completes normally, always throws an error
*/
export function handleApiError(this: IExecuteFunctions, error: any, message?: string): never {
logger.error('error:api', { originalMessage: error.message, customMessage: message });
// Special handling for rate limiting errors
if (error.message && error.message.includes('rate limit')) {
let retryAfter = 'unknown time';
// Try to extract the retry time from the error message
const retryMatch = error.message.match(/(\d+) seconds/);
if (retryMatch && retryMatch[1]) {
retryAfter = `${retryMatch[1]} seconds`;
}
const rateMessage = `API rate limited. Please retry after ${retryAfter}.`;
logger.error('error:ratelimit', rateMessage);
throw new NodeOperationError(this.getNode(), rateMessage);
}
if (error.response?.body) {
const errorBody = error.response.body;
let errorMessage = message || 'Unknown error';
// Check for rate limiting in the response body
if (
typeof errorBody === 'object' &&
errorBody.message &&
errorBody.message.includes('rate limit')
) {
let retryAfter = 'unknown time';
// Try to extract the retry time from the message
const retryMatch = errorBody.message.match(/(\d+) seconds/);
if (retryMatch && retryMatch[1]) {
retryAfter = `${retryMatch[1]} seconds`;
}
const rateMessage = `API rate limited. Please retry after ${retryAfter}.`;
logger.error('error:ratelimit', rateMessage);
throw new NodeOperationError(this.getNode(), rateMessage);
}
// Process other types of error messages
if (typeof errorBody === 'object') {
if (errorBody.description) {
errorMessage = errorBody.description;
} else if (errorBody.error_description) {
errorMessage = errorBody.error_description;
} else if (errorBody.message) {
errorMessage = errorBody.message;
} else if (errorBody.detail) {
errorMessage = errorBody.detail;
}
} else if (typeof errorBody === 'string') {
try {
const parsedBody = JSON.parse(errorBody);
if (parsedBody.message) {
errorMessage = parsedBody.message;
}
} catch (e) {
// If parsing fails, use the string directly if it's not too long
if (errorBody.length < 300) {
errorMessage = errorBody;
}
}
}
logger.error('error:api', `Throwing NodeApiError with message: ${errorMessage}`);
throw new NodeApiError(this.getNode(), error, { message: errorMessage });
}
if (message) {
logger.error('error:operation', `Throwing NodeOperationError with message: ${message}`);
throw new NodeOperationError(this.getNode(), message);
}
logger.error('error:unknown', 'Re-throwing original error');
throw error;
}
/**
* Handle validation errors
*
* @param this The n8n execution context
* @param message Error message describing the validation failure
* @returns Never completes normally, always throws an error
*/
export function handleValidationError(this: IExecuteFunctions, message: string): never {
logger.error('error:validation', message);
throw new NodeOperationError(this.getNode(), message);
}
/**
* Handle API errors while allowing execution to continue
*
* @param this The n8n execution context
* @param error The error that was caught
* @param message Optional custom error message
* @returns Array with a single item containing error details
*/
export function handleApiErrorWithContinue(
this: IExecuteFunctions,
error: any,
message?: string,
): INodeExecutionData[] {
logger.error('error:api:continue', { originalMessage: error.message, customMessage: message });
// Special handling for rate limiting errors
let errorMessage = message || error.message || 'Unknown error occurred';
// Check for rate limiting in the error message
if (error.message && error.message.includes('rate limit')) {
let retryAfter = 'unknown time';
// Try to extract the retry time from the error message
const retryMatch = error.message.match(/(\d+) seconds/);
if (retryMatch && retryMatch[1]) {
retryAfter = `${retryMatch[1]} seconds`;
}
errorMessage = `API rate limited. Please retry after ${retryAfter}.`;
logger.error('error:ratelimit', errorMessage);
}
// If continueOnFail is enabled, return error as data
if (this.continueOnFail()) {
logger.debug('error:api:continue', `Continuing execution with error: ${errorMessage}`);
return [
{
json: {
success: false,
error: errorMessage,
details: error.response?.body || {},
},
},
];
}
// Otherwise handle as regular error (will throw)
return handleApiError.call(this, error, errorMessage) as never;
}