fix(core): Assign Unknown Error only if message or description not present in error

This commit is contained in:
Michael Kret 2023-05-03 10:15:33 +03:00 committed by GitHub
parent deb4c04f34
commit 8aedc03dda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 128 additions and 4 deletions

View file

@ -270,7 +270,8 @@ const STATUS_CODE_MESSAGES: IStatusCodeMessages = {
'5XX': 'The service failed to process your request',
'500': 'The service was not able to process 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?',
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 = {},
) {
super(node, error);
if (error.error) {
// only for request library error
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
// look for descriptions in the response object
if (error.reason) {
const reason: IDataObject = error.reason as unknown as IDataObject;
if (reason.isAxiosError && reason.response) {
error = reason.response as JsonObject;
}
@ -319,7 +356,12 @@ export class NodeApiError extends NodeError {
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();
if (parseXml) {
@ -356,7 +398,8 @@ export class NodeApiError extends NodeError {
private setMessage() {
if (!this.httpCode) {
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;
}
@ -373,7 +416,8 @@ export class NodeApiError extends NodeError {
this.message = STATUS_CODE_MESSAGES['5XX'];
break;
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) {
this.message = `${UNKNOWN_ERROR_MESSAGE_CRED} - ${this.httpCode}`;

View 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');
});
});