mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix(core): Assign Unknown Error only if message or description not present in error
This commit is contained in:
parent
deb4c04f34
commit
8aedc03dda
|
@ -270,7 +270,8 @@ const STATUS_CODE_MESSAGES: IStatusCodeMessages = {
|
||||||
'5XX': 'The service failed to process your request',
|
'5XX': 'The service failed to process your request',
|
||||||
'500': 'The service was not able to process your request',
|
'500': 'The service was not able to process your request',
|
||||||
'502': 'Bad gateway - the service failed to handle your request',
|
'502': 'Bad gateway - the service failed to handle your request',
|
||||||
'503': 'Service unavailable - perhaps try again later?',
|
'503':
|
||||||
|
'Service unavailable - try again later or consider setting this node to retry automatically (in the node settings)',
|
||||||
'504': 'Gateway timed out - perhaps try again later?',
|
'504': 'Gateway timed out - perhaps try again later?',
|
||||||
|
|
||||||
ECONNREFUSED: 'The service refused the connection - perhaps it is offline',
|
ECONNREFUSED: 'The service refused the connection - perhaps it is offline',
|
||||||
|
@ -298,15 +299,51 @@ export class NodeApiError extends NodeError {
|
||||||
{ message, description, httpCode, parseXml, runIndex, itemIndex }: NodeApiErrorOptions = {},
|
{ message, description, httpCode, parseXml, runIndex, itemIndex }: NodeApiErrorOptions = {},
|
||||||
) {
|
) {
|
||||||
super(node, error);
|
super(node, error);
|
||||||
|
|
||||||
if (error.error) {
|
if (error.error) {
|
||||||
// only for request library error
|
// only for request library error
|
||||||
this.removeCircularRefs(error.error as JsonObject);
|
this.removeCircularRefs(error.error as JsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((!message && (error.message || (error?.reason as IDataObject)?.message)) || description) {
|
||||||
|
this.message = (error.message ??
|
||||||
|
(error?.reason as IDataObject)?.message ??
|
||||||
|
description) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!description && (error.description || (error?.reason as IDataObject)?.description)) {
|
||||||
|
this.description = (error.description ??
|
||||||
|
(error?.reason as IDataObject)?.description) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!httpCode && !message && error.status === 'rejected') {
|
||||||
|
httpCode = 'ECONNREFUSED';
|
||||||
|
|
||||||
|
const originalMessage = this.message;
|
||||||
|
if (!description && originalMessage) {
|
||||||
|
this.description = `${originalMessage} ${this.description ?? ''}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!httpCode &&
|
||||||
|
!message &&
|
||||||
|
this.message &&
|
||||||
|
this.message.toLowerCase().includes('bad gateway')
|
||||||
|
) {
|
||||||
|
httpCode = '502';
|
||||||
|
|
||||||
|
const originalMessage = this.message;
|
||||||
|
if (!description) {
|
||||||
|
this.description = `${originalMessage}; ${this.description ?? ''}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if it's an error generated by axios
|
// if it's an error generated by axios
|
||||||
// look for descriptions in the response object
|
// look for descriptions in the response object
|
||||||
if (error.reason) {
|
if (error.reason) {
|
||||||
const reason: IDataObject = error.reason as unknown as IDataObject;
|
const reason: IDataObject = error.reason as unknown as IDataObject;
|
||||||
|
|
||||||
if (reason.isAxiosError && reason.response) {
|
if (reason.isAxiosError && reason.response) {
|
||||||
error = reason.response as JsonObject;
|
error = reason.response as JsonObject;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +356,12 @@ export class NodeApiError extends NodeError {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.httpCode = this.findProperty(error, ERROR_STATUS_PROPERTIES, ERROR_NESTING_PROPERTIES);
|
if (httpCode) {
|
||||||
|
this.httpCode = httpCode;
|
||||||
|
} else {
|
||||||
|
this.httpCode = this.findProperty(error, ERROR_STATUS_PROPERTIES, ERROR_NESTING_PROPERTIES);
|
||||||
|
}
|
||||||
|
|
||||||
this.setMessage();
|
this.setMessage();
|
||||||
|
|
||||||
if (parseXml) {
|
if (parseXml) {
|
||||||
|
@ -356,7 +398,8 @@ export class NodeApiError extends NodeError {
|
||||||
private setMessage() {
|
private setMessage() {
|
||||||
if (!this.httpCode) {
|
if (!this.httpCode) {
|
||||||
this.httpCode = null;
|
this.httpCode = null;
|
||||||
this.message = UNKNOWN_ERROR_MESSAGE;
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||||
|
this.message = this.message || this.description || UNKNOWN_ERROR_MESSAGE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +416,8 @@ export class NodeApiError extends NodeError {
|
||||||
this.message = STATUS_CODE_MESSAGES['5XX'];
|
this.message = STATUS_CODE_MESSAGES['5XX'];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.message = this.message || UNKNOWN_ERROR_MESSAGE;
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||||
|
this.message = this.message || this.description || UNKNOWN_ERROR_MESSAGE;
|
||||||
}
|
}
|
||||||
if (this.node.type === 'n8n-nodes-base.noOp' && this.message === UNKNOWN_ERROR_MESSAGE) {
|
if (this.node.type === 'n8n-nodes-base.noOp' && this.message === UNKNOWN_ERROR_MESSAGE) {
|
||||||
this.message = `${UNKNOWN_ERROR_MESSAGE_CRED} - ${this.httpCode}`;
|
this.message = `${UNKNOWN_ERROR_MESSAGE_CRED} - ${this.httpCode}`;
|
||||||
|
|
80
packages/workflow/test/NodeErrors.test.ts
Normal file
80
packages/workflow/test/NodeErrors.test.ts
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import type { INode } from '../src/Interfaces';
|
||||||
|
import { NodeApiError } from '../src/NodeErrors';
|
||||||
|
|
||||||
|
const node: INode = {
|
||||||
|
id: '1',
|
||||||
|
name: 'Postgres node',
|
||||||
|
typeVersion: 2,
|
||||||
|
type: 'n8n-nodes-base.postgres',
|
||||||
|
position: [60, 760],
|
||||||
|
parameters: {
|
||||||
|
operation: 'executeQuery',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('NodeErrors tests', () => {
|
||||||
|
it('should return unknown error message', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {});
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual(
|
||||||
|
'UNKNOWN ERROR - check the detailed error for more information',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the error message', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, { message: 'test error message' });
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error message');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the error message defined in reason', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, { reason: { message: 'test error message' } });
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error message');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the error message defined in options', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {}, { message: 'test error message' });
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error message');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return description error message', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, { description: 'test error description' });
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error description');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return description as error message defined in reason', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {
|
||||||
|
reason: { description: 'test error description' },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error description');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return description as error message defined in options', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {}, { description: 'test error description' });
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('test error description');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return default message for ECONNREFUSED', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {
|
||||||
|
status: 'rejected',
|
||||||
|
message: 'ECONNREFUSED',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual(
|
||||||
|
'The service refused the connection - perhaps it is offline',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return default message for 502', () => {
|
||||||
|
const nodeApiError = new NodeApiError(node, {
|
||||||
|
message: '502 Bad Gateway',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(nodeApiError.message).toEqual('Bad gateway - the service failed to handle your request');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue