mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-19 07:36:52 +00:00
refactor: Replace deprecated ApplicationError in credentials (no-changelog) (#32230)
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import type {
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
import { type AwsAssumeRoleCredentialsType, type AWSRegion } from './common/aws/types';
|
||||
import { awsCustomEndpoints, awsRegionProperty } from './common/aws/descriptions';
|
||||
@@ -142,7 +142,7 @@ export class AwsAssumeRole implements ICredentialType {
|
||||
finalCredentials = { ...credentials, ...securityHeaders };
|
||||
} catch (error) {
|
||||
console.error('Failed to assume role:', error);
|
||||
throw new ApplicationError(
|
||||
throw new UserError(
|
||||
`Failed to assume role: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ApplicationError } from '@n8n/errors';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialType,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
export class CustomerIoApi implements ICredentialType {
|
||||
name = 'customerIoApi';
|
||||
@@ -91,7 +91,7 @@ export class CustomerIoApi implements ICredentialType {
|
||||
Authorization: `Bearer ${credentials.appApiKey as string}`,
|
||||
});
|
||||
} else {
|
||||
throw new ApplicationError('Unknown way of authenticating', { level: 'warning' });
|
||||
throw new UserError('Unknown way of authenticating', { level: 'warning' });
|
||||
}
|
||||
|
||||
return requestOptions;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ApplicationError } from '@n8n/errors';
|
||||
import type {
|
||||
IAuthenticateGeneric,
|
||||
ICredentialDataDecryptedObject,
|
||||
@@ -8,6 +7,7 @@ import type {
|
||||
INodeProperties,
|
||||
Icon,
|
||||
} from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
export class ZscalerZiaApi implements ICredentialType {
|
||||
name = 'zscalerZiaApi';
|
||||
@@ -122,7 +122,7 @@ export class ZscalerZiaApi implements ICredentialType {
|
||||
?.find((entry) => entry.includes('JSESSIONID'));
|
||||
|
||||
if (!cookie) {
|
||||
throw new ApplicationError('No cookie returned. Please check your credentials.', {
|
||||
throw new UserError('No cookie returned. Please check your credentials.', {
|
||||
level: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
global.fetch = jest.fn();
|
||||
|
||||
@@ -60,10 +60,10 @@ describe('system-credentials-utils', () => {
|
||||
});
|
||||
|
||||
describe('getSystemCredentials', () => {
|
||||
it('should throw ApplicationError when AWS system credentials access is disabled', async () => {
|
||||
it('should throw UserError when AWS system credentials access is disabled', async () => {
|
||||
mockSecurityConfigInstance.awsSystemCredentialsAccess = false;
|
||||
|
||||
await expect(getSystemCredentials()).rejects.toThrow(ApplicationError);
|
||||
await expect(getSystemCredentials()).rejects.toThrow(UserError);
|
||||
await expect(getSystemCredentials()).rejects.toThrow(
|
||||
'Access to AWS system credentials disabled, contact your administrator.',
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { SecurityConfig } from '@n8n/config';
|
||||
import { Container } from '@n8n/di';
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
type Resolvers =
|
||||
@@ -36,9 +36,7 @@ export const credentialsResolver: Record<Resolvers, () => Promise<ReturnData | n
|
||||
*/
|
||||
export async function getSystemCredentials() {
|
||||
if (!Container.get(SecurityConfig).awsSystemCredentialsAccess) {
|
||||
throw new ApplicationError(
|
||||
'Access to AWS system credentials disabled, contact your administrator.',
|
||||
);
|
||||
throw new UserError('Access to AWS system credentials disabled, contact your administrator.');
|
||||
}
|
||||
|
||||
const resolveOrder: Resolvers[] = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { OperationalError, UserError } from 'n8n-workflow';
|
||||
import type { AwsAssumeRoleCredentialsType, AwsIamCredentialsType, AWSRegion } from './types';
|
||||
|
||||
global.fetch = jest.fn();
|
||||
@@ -203,7 +203,7 @@ describe('assumeRole', () => {
|
||||
|
||||
jest.spyOn(systemCredentialsUtils, 'getSystemCredentials').mockResolvedValue(null);
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'System AWS credentials are required for role assumption',
|
||||
);
|
||||
@@ -371,7 +371,7 @@ describe('assumeRole', () => {
|
||||
stsSecretAccessKey: 'sts-secret-key',
|
||||
};
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'STS Access Key ID is required when not using system credentials',
|
||||
);
|
||||
@@ -389,7 +389,7 @@ describe('assumeRole', () => {
|
||||
stsSecretAccessKey: 'sts-secret-key',
|
||||
};
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'STS Access Key ID is required when not using system credentials',
|
||||
);
|
||||
@@ -406,7 +406,7 @@ describe('assumeRole', () => {
|
||||
stsAccessKeyId: 'sts-access-key',
|
||||
};
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'STS Secret Access Key is required when not using system credentials',
|
||||
);
|
||||
@@ -424,7 +424,7 @@ describe('assumeRole', () => {
|
||||
stsSecretAccessKey: ' ',
|
||||
};
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'STS Secret Access Key is required when not using system credentials',
|
||||
);
|
||||
@@ -575,7 +575,7 @@ describe('assumeRole', () => {
|
||||
throw new Error('Signing failed');
|
||||
});
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(OperationalError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'Failed to sign STS request',
|
||||
);
|
||||
@@ -602,7 +602,7 @@ describe('assumeRole', () => {
|
||||
|
||||
mockFetch.mockResolvedValue(mockResponse as any);
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'STS AssumeRole failed: 403 Forbidden - Access denied',
|
||||
);
|
||||
@@ -661,7 +661,7 @@ describe('assumeRole', () => {
|
||||
});
|
||||
});
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(OperationalError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'Invalid response from STS AssumeRole',
|
||||
);
|
||||
@@ -692,7 +692,7 @@ describe('assumeRole', () => {
|
||||
});
|
||||
});
|
||||
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(OperationalError);
|
||||
await expect(assumeRole(credentials, 'us-east-1')).rejects.toThrow(
|
||||
'Invalid response from STS AssumeRole',
|
||||
);
|
||||
@@ -772,14 +772,14 @@ describe('assertSupportedAwsRegion', () => {
|
||||
['169.254.169.254'],
|
||||
['localhost'],
|
||||
])('rejects unsupported region value %s', (region) => {
|
||||
expect(() => assertSupportedAwsRegion(region)).toThrow(ApplicationError);
|
||||
expect(() => assertSupportedAwsRegion(region)).toThrow(UserError);
|
||||
expect(() => assertSupportedAwsRegion(region)).toThrow('Unsupported AWS region');
|
||||
});
|
||||
|
||||
it.each([[undefined], [null], [0], [true], [{}], [['us-east-1']]])(
|
||||
'rejects non-string region value %s',
|
||||
(region) => {
|
||||
expect(() => assertSupportedAwsRegion(region)).toThrow(ApplicationError);
|
||||
expect(() => assertSupportedAwsRegion(region)).toThrow(UserError);
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -839,7 +839,7 @@ describe('awsGetSignInOptionsAndUpdateRequest', () => {
|
||||
'lambda',
|
||||
region as any,
|
||||
),
|
||||
).toThrow(ApplicationError);
|
||||
).toThrow(UserError);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -872,7 +872,7 @@ describe('assumeRole region validation', () => {
|
||||
stsSecretAccessKey: 'sts-secret-key',
|
||||
};
|
||||
|
||||
await expect(assumeRole(credentials, region as any)).rejects.toThrow(ApplicationError);
|
||||
await expect(assumeRole(credentials, region as any)).rejects.toThrow(UserError);
|
||||
await expect(assumeRole(credentials, region as any)).rejects.toThrow(
|
||||
'Unsupported AWS region',
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { resolveProxyUrl } from '@n8n/backend-network';
|
||||
import {
|
||||
ApplicationError,
|
||||
type IHttpRequestMethods,
|
||||
isObjectEmpty,
|
||||
sanitizeXmlName,
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
type IDataObject,
|
||||
type IHttpRequestOptions,
|
||||
type IRequestOptions,
|
||||
OperationalError,
|
||||
UserError,
|
||||
} from 'n8n-workflow';
|
||||
import { parseString } from 'xml2js';
|
||||
@@ -52,7 +52,7 @@ const SUPPORTED_AWS_REGIONS: ReadonlySet<string> = new Set(regions.map((r) => r.
|
||||
*/
|
||||
export function assertSupportedAwsRegion(region: unknown): asserts region is AWSRegion {
|
||||
if (typeof region !== 'string' || !SUPPORTED_AWS_REGIONS.has(region)) {
|
||||
throw new ApplicationError('Unsupported AWS region');
|
||||
throw new UserError('Unsupported AWS region');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ export function awsGetSignInOptionsAndUpdateRequest(
|
||||
* @param credentials - The assume role credentials configuration
|
||||
* @param region - AWS region for the STS endpoint
|
||||
* @returns Promise resolving to temporary credentials for the assumed role
|
||||
* @throws {ApplicationError} When credentials are invalid or STS call fails
|
||||
* @throws {UserError | OperationalError} When credentials are invalid or STS call fails
|
||||
*
|
||||
* @see {@link https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html STS AssumeRole API}
|
||||
*/
|
||||
@@ -312,7 +312,7 @@ export async function assumeRole(
|
||||
if (useSystemCredentialsForRole) {
|
||||
const systemCredentials = await getSystemCredentials();
|
||||
if (!systemCredentials) {
|
||||
throw new ApplicationError(
|
||||
throw new UserError(
|
||||
'System AWS credentials are required for role assumption. Please ensure AWS credentials are available via environment variables, instance metadata, or container role.',
|
||||
);
|
||||
}
|
||||
@@ -320,14 +320,10 @@ export async function assumeRole(
|
||||
stsCallCredentials = systemCredentials;
|
||||
} else {
|
||||
if (!credentials.stsAccessKeyId || credentials.stsAccessKeyId.trim() === '') {
|
||||
throw new ApplicationError(
|
||||
'STS Access Key ID is required when not using system credentials.',
|
||||
);
|
||||
throw new UserError('STS Access Key ID is required when not using system credentials.');
|
||||
}
|
||||
if (!credentials.stsSecretAccessKey || credentials.stsSecretAccessKey.trim() === '') {
|
||||
throw new ApplicationError(
|
||||
'STS Secret Access Key is required when not using system credentials.',
|
||||
);
|
||||
throw new UserError('STS Secret Access Key is required when not using system credentials.');
|
||||
}
|
||||
|
||||
const sessionToken = credentials.stsSessionToken?.trim() || undefined;
|
||||
@@ -376,7 +372,7 @@ export async function assumeRole(
|
||||
sign(signOpts, stsCallCredentials);
|
||||
} catch (err) {
|
||||
console.error('Failed to sign STS request:', err);
|
||||
throw new ApplicationError('Failed to sign STS request');
|
||||
throw new OperationalError('Failed to sign STS request');
|
||||
}
|
||||
|
||||
const proxyUrl = resolveProxyUrl(stsEndpoint);
|
||||
@@ -391,7 +387,7 @@ export async function assumeRole(
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new ApplicationError(
|
||||
throw new UserError(
|
||||
`STS AssumeRole failed: ${response.status} ${response.statusText} - ${errorText}`,
|
||||
);
|
||||
}
|
||||
@@ -418,7 +414,7 @@ export async function assumeRole(
|
||||
const assumeRoleResult = (responseData.AssumeRoleResponse as IDataObject)
|
||||
?.AssumeRoleResult as IDataObject;
|
||||
if (!assumeRoleResult?.Credentials) {
|
||||
throw new ApplicationError('Invalid response from STS AssumeRole');
|
||||
throw new OperationalError('Invalid response from STS AssumeRole');
|
||||
}
|
||||
|
||||
const assumedCredentials = assumeRoleResult.Credentials as IDataObject;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { ICredentialTestFunctions } from 'n8n-workflow';
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
jest.mock('aws4', () => ({
|
||||
sign: jest.fn(),
|
||||
@@ -44,7 +44,7 @@ describe('AWS Textract Generic Functions', () => {
|
||||
const credentials = { ...baseCredentials, region };
|
||||
|
||||
await expect(validateCredentials.call(context, credentials, 'textract')).rejects.toThrow(
|
||||
ApplicationError,
|
||||
UserError,
|
||||
);
|
||||
await expect(validateCredentials.call(context, credentials, 'textract')).rejects.toThrow(
|
||||
'Unsupported AWS region',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { IExecuteFunctions } from 'n8n-workflow';
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { UserError } from 'n8n-workflow';
|
||||
|
||||
jest.mock('aws4', () => ({
|
||||
sign: jest.fn(),
|
||||
@@ -57,7 +57,7 @@ describe('AWS Transcribe Generic Functions', () => {
|
||||
const { context, helpers } = buildContext(region);
|
||||
|
||||
await expect(awsApiRequest.call(context, 'transcribe', 'POST', '/')).rejects.toThrow(
|
||||
ApplicationError,
|
||||
UserError,
|
||||
);
|
||||
await expect(awsApiRequest.call(context, 'transcribe', 'POST', '/')).rejects.toThrow(
|
||||
'Unsupported AWS region',
|
||||
|
||||
Reference in New Issue
Block a user