mirror of
https://github.com/n8n-io/n8n
synced 2026-04-21 15:47:20 +00:00
fix(GraphQL Node): Improve error response handling (#28209)
This commit is contained in:
parent
98b833a07d
commit
357fb7210a
2 changed files with 86 additions and 3 deletions
|
|
@ -552,9 +552,15 @@ export class GraphQL implements INodeType {
|
|||
}
|
||||
// throw from response object.errors[]
|
||||
if (typeof response === 'object' && response.errors) {
|
||||
const message =
|
||||
response.errors?.map((error: IDataObject) => error.message).join(', ') ||
|
||||
'Unexpected error';
|
||||
let message = 'Unexpected error';
|
||||
if (Array.isArray(response.errors)) {
|
||||
message = (response.errors as IDataObject[])
|
||||
.map((error) => error.message ?? error)
|
||||
.join(', ');
|
||||
} else if (typeof response.errors === 'string') {
|
||||
message = response.errors;
|
||||
}
|
||||
|
||||
throw new NodeApiError(this.getNode(), response.errors as JsonObject, { message });
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import { mockDeep } from 'jest-mock-extended';
|
||||
import get from 'lodash/get';
|
||||
import { constructExecutionMetaData, returnJsonArray } from 'n8n-core';
|
||||
import type { IDataObject, IExecuteFunctions } from 'n8n-workflow';
|
||||
import nock from 'nock';
|
||||
|
||||
import { GraphQL } from '../GraphQL.node';
|
||||
|
||||
describe('GraphQL Node', () => {
|
||||
describe('valid request', () => {
|
||||
const baseUrl = 'https://api.n8n.io/';
|
||||
|
|
@ -110,4 +116,75 @@ describe('GraphQL Node', () => {
|
|||
credentials,
|
||||
});
|
||||
});
|
||||
|
||||
describe('error response', () => {
|
||||
const createMockExecuteFunctions = (parameters: IDataObject) => {
|
||||
const mockExecuteFunctions = mockDeep<IExecuteFunctions>();
|
||||
mockExecuteFunctions.getNodeParameter.mockImplementation((parameter, _idx, fallbackValue) => {
|
||||
return get(parameters, parameter) ?? fallbackValue;
|
||||
});
|
||||
mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]);
|
||||
mockExecuteFunctions.helpers.returnJsonArray.mockImplementation(returnJsonArray);
|
||||
mockExecuteFunctions.helpers.constructExecutionMetaData.mockImplementation(
|
||||
constructExecutionMetaData,
|
||||
);
|
||||
return mockExecuteFunctions;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should format error response if response.errors is an array with objects', async () => {
|
||||
const mockExecuteFunctions = createMockExecuteFunctions({
|
||||
query: 'query { foo }',
|
||||
});
|
||||
mockExecuteFunctions.helpers.request.mockResolvedValue({
|
||||
errors: [{ message: 'Bad format 1' }, { message: 'Bad format 2' }],
|
||||
});
|
||||
const node = new GraphQL();
|
||||
|
||||
await expect(node.execute.call(mockExecuteFunctions)).rejects.toThrow(
|
||||
'Bad format 1, Bad format 2',
|
||||
);
|
||||
});
|
||||
|
||||
it('should format error response if response.errors is an array with strings', async () => {
|
||||
const mockExecuteFunctions = createMockExecuteFunctions({
|
||||
query: 'query { foo }',
|
||||
});
|
||||
mockExecuteFunctions.helpers.request.mockResolvedValue({
|
||||
errors: ['Bad format 1', 'Bad format 2'],
|
||||
});
|
||||
const node = new GraphQL();
|
||||
|
||||
await expect(node.execute.call(mockExecuteFunctions)).rejects.toThrow(
|
||||
'Bad format 1, Bad format 2',
|
||||
);
|
||||
});
|
||||
|
||||
it('should format error response if response.errors is a string', async () => {
|
||||
const mockExecuteFunctions = createMockExecuteFunctions({
|
||||
query: 'query { foo }',
|
||||
});
|
||||
mockExecuteFunctions.helpers.request.mockResolvedValue({
|
||||
errors: 'Bad format',
|
||||
});
|
||||
const node = new GraphQL();
|
||||
|
||||
await expect(node.execute.call(mockExecuteFunctions)).rejects.toThrow('Bad format');
|
||||
});
|
||||
|
||||
it('should fallback to unexpected error if response.errors is not an array or string', async () => {
|
||||
const mockExecuteFunctions = createMockExecuteFunctions({
|
||||
query: 'query { foo }',
|
||||
});
|
||||
mockExecuteFunctions.helpers.request.mockResolvedValue({
|
||||
errors: 123,
|
||||
});
|
||||
const node = new GraphQL();
|
||||
|
||||
await expect(node.execute.call(mockExecuteFunctions)).rejects.toThrow('Unexpected error');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue