mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
✨ Improve node error handling (#1309)
* Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * 🚧 create basic setup NodeError * 🚧 add httpCodes * 🚧 add path priolist * 🚧 handle statusCode in error, adjust interfaces * 🚧 fixing type issues w/Ivan * 🚧 add error exploration * 👔 fix linter issues * 🔧 improve object check * 🚧 remove path passing from NodeApiError * 🚧 add multi error + refactor findProperty method * 👔 allow any * 🔧 handle multi error message callback * ⚡ change return type of callback * ⚡ add customCallback to MultiError * 🚧 refactor to use INode * 🔨 handle arrays, continue search after first null property found * 🚫 refactor method access * 🚧 setup NodeErrorView * ⚡ change timestamp to Date.now * 📚 Add documentation for methods and constants * 🚧 change message setting * 🚚 move NodeErrors to workflow * ✨ add new ErrorView for Nodes * 🎨 improve error notification * 🎨 refactor interfaces * ⚡ add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * 🎨 rename param * 🐛 fix handling normal errors * ⚡ add usage of NodeApiError * 🎨 fix throw new error instead of constructor * 🎨 remove unnecessary code/comments * 🎨 adjusted spacing + updated status messages * 🎨 fix tab indentation * ✨ Replace current errors with custom errors (#1576) * ⚡ Introduce NodeApiError in catch blocks * ⚡ Introduce NodeOperationError in nodes * ⚡ Add missing errors and remove incompatible * ⚡ Fix NodeOperationError in incompatible nodes * 🔧 Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * 🔨 Adjust Strava Trigger node error handling * 🔨 Adjust AWS nodes error handling * 🔨 Remove duplicate instantiation of NodeApiError * 🐛 fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * 🐛 Remove type annotation from catch variable * ✨ Add XML parsing to NodeApiError * ⚡ Simplify error handling in Rekognition node * ⚡ Pass in XML flag in generic functions * 🔥 Remove try/catch wrappers at call sites * 🔨 Refactor setting description from XML * 🔨 Refactor let to const in resource loaders * ⚡ Find property in parsed XML * ⚡ Change let to const * 🔥 Remove unneeded try/catch block * 👕 Fix linting issues * 🐛 Fix errors from merge conflict resolution * ⚡ Add custom errors to latest contributions * 👕 Fix linting issues * ⚡ Refactor MongoDB helpers for custom errors * 🐛 Correct custom error type * ⚡ Apply feedback to A nodes * ⚡ Apply feedback to missed A node * ⚡ Apply feedback to B-D nodes * ⚡ Apply feedback to E-F nodes * ⚡ Apply feedback to G nodes * ⚡ Apply feedback to H-L nodes * ⚡ Apply feedback to M nodes * ⚡ Apply feedback to P nodes * ⚡ Apply feedback to R nodes * ⚡ Apply feedback to S nodes * ⚡ Apply feedback to T nodes * ⚡ Apply feedback to V-Z nodes * ⚡ Add HTTP code to iterable node error * 🔨 Standardize e as error * 🔨 Standardize err as error * ⚡ Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
This commit is contained in:
parent
1a0e129921
commit
1d27a9e87e
|
@ -167,10 +167,11 @@ export class Execute extends Command {
|
||||||
this.log('====================================');
|
this.log('====================================');
|
||||||
this.log(JSON.stringify(data, null, 2));
|
this.log(JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
// console.log(data.data.resultData.error);
|
const { error } = data.data.resultData;
|
||||||
const error = new Error(data.data.resultData.error.message);
|
throw {
|
||||||
error.stack = data.data.resultData.error.stack;
|
...error,
|
||||||
throw error;
|
stack: error.stack,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log('Execution was successfull:');
|
this.log('Execution was successfull:');
|
||||||
|
@ -182,7 +183,6 @@ export class Execute extends Command {
|
||||||
console.error(e.message);
|
console.error(e.message);
|
||||||
console.error(e.stack);
|
console.error(e.stack);
|
||||||
this.exit(1);
|
this.exit(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.exit();
|
this.exit();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {
|
import {
|
||||||
|
ExecutionError,
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject,
|
||||||
ICredentialsDecrypted,
|
ICredentialsDecrypted,
|
||||||
ICredentialsEncrypted,
|
ICredentialsEncrypted,
|
||||||
ICredentialType,
|
ICredentialType,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecutionError,
|
|
||||||
IRun,
|
IRun,
|
||||||
IRunData,
|
IRunData,
|
||||||
IRunExecutionData,
|
IRunExecutionData,
|
||||||
|
@ -18,7 +18,6 @@ import {
|
||||||
IDeferredPromise,
|
IDeferredPromise,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
|
||||||
import * as PCancelable from 'p-cancelable';
|
import * as PCancelable from 'p-cancelable';
|
||||||
import { ObjectID, Repository } from 'typeorm';
|
import { ObjectID, Repository } from 'typeorm';
|
||||||
|
|
||||||
|
@ -374,10 +373,10 @@ export interface ITransferNodeTypes {
|
||||||
|
|
||||||
|
|
||||||
export interface IWorkflowErrorData {
|
export interface IWorkflowErrorData {
|
||||||
[key: string]: IDataObject | string | number | IExecutionError;
|
[key: string]: IDataObject | string | number | ExecutionError;
|
||||||
execution: {
|
execution: {
|
||||||
id?: string;
|
id?: string;
|
||||||
error: IExecutionError;
|
error: ExecutionError;
|
||||||
lastNodeExecuted: string;
|
lastNodeExecuted: string;
|
||||||
mode: WorkflowExecuteMode;
|
mode: WorkflowExecuteMode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,7 +144,7 @@ export function getWorkflowWebhooksBasic(workflow: Workflow): IWebhookData[] {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
webhookResultData = await workflow.runWebhook(webhookData, workflowStartNode, additionalData, NodeExecuteFunctions, executionMode);
|
webhookResultData = await workflow.runWebhook(webhookData, workflowStartNode, additionalData, NodeExecuteFunctions, executionMode);
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
// Send error response to webhook caller
|
// Send error response to webhook caller
|
||||||
const errorMessage = 'Workflow Webhook Error: Workflow could not be started!';
|
const errorMessage = 'Workflow Webhook Error: Workflow could not be started!';
|
||||||
responseCallback(new Error(errorMessage), {});
|
responseCallback(new Error(errorMessage), {});
|
||||||
|
@ -156,8 +156,9 @@ export function getWorkflowWebhooksBasic(workflow: Workflow): IWebhookData[] {
|
||||||
runData: {},
|
runData: {},
|
||||||
lastNodeExecuted: workflowStartNode.name,
|
lastNodeExecuted: workflowStartNode.name,
|
||||||
error: {
|
error: {
|
||||||
message: e.message,
|
...err,
|
||||||
stack: e.stack,
|
message: err.message,
|
||||||
|
stack: err.stack,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -627,9 +627,11 @@ export async function executeWorkflow(workflowInfo: IExecuteWorkflowInfo, additi
|
||||||
} else {
|
} else {
|
||||||
await ActiveExecutions.getInstance().remove(executionId, data);
|
await ActiveExecutions.getInstance().remove(executionId, data);
|
||||||
// Workflow did fail
|
// Workflow did fail
|
||||||
const error = new Error(data.data.resultData.error!.message);
|
const { error } = data.data.resultData;
|
||||||
error.stack = data.data.resultData.error!.stack;
|
throw {
|
||||||
throw error;
|
...error,
|
||||||
|
stack: error!.stack,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
ExecutionError,
|
||||||
IExecutionError,
|
|
||||||
IRun,
|
IRun,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowExecuteMode,
|
WorkflowExecuteMode,
|
||||||
WorkflowHooks,
|
WorkflowHooks,
|
||||||
|
WorkflowOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import * as config from '../config';
|
import * as config from '../config';
|
||||||
|
@ -78,13 +78,13 @@ export class WorkflowRunner {
|
||||||
/**
|
/**
|
||||||
* The process did error
|
* The process did error
|
||||||
*
|
*
|
||||||
* @param {IExecutionError} error
|
* @param {ExecutionError} error
|
||||||
* @param {Date} startedAt
|
* @param {Date} startedAt
|
||||||
* @param {WorkflowExecuteMode} executionMode
|
* @param {WorkflowExecuteMode} executionMode
|
||||||
* @param {string} executionId
|
* @param {string} executionId
|
||||||
* @memberof WorkflowRunner
|
* @memberof WorkflowRunner
|
||||||
*/
|
*/
|
||||||
processError(error: IExecutionError, startedAt: Date, executionMode: WorkflowExecuteMode, executionId: string) {
|
processError(error: ExecutionError, startedAt: Date, executionMode: WorkflowExecuteMode, executionId: string) {
|
||||||
const fullRunData: IRun = {
|
const fullRunData: IRun = {
|
||||||
data: {
|
data: {
|
||||||
resultData: {
|
resultData: {
|
||||||
|
@ -250,9 +250,7 @@ export class WorkflowRunner {
|
||||||
const fullRunData :IRun = {
|
const fullRunData :IRun = {
|
||||||
data: {
|
data: {
|
||||||
resultData: {
|
resultData: {
|
||||||
error: {
|
error: new WorkflowOperationError('Workflow has been canceled!'),
|
||||||
message: 'Workflow has been canceled!',
|
|
||||||
} as IExecutionError,
|
|
||||||
runData: {},
|
runData: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -464,14 +462,14 @@ export class WorkflowRunner {
|
||||||
|
|
||||||
} else if (message.type === 'processError') {
|
} else if (message.type === 'processError') {
|
||||||
clearTimeout(executionTimeout);
|
clearTimeout(executionTimeout);
|
||||||
const executionError = message.data.executionError as IExecutionError;
|
const executionError = message.data.executionError as ExecutionError;
|
||||||
this.processError(executionError, startedAt, data.executionMode, executionId);
|
this.processError(executionError, startedAt, data.executionMode, executionId);
|
||||||
|
|
||||||
} else if (message.type === 'processHook') {
|
} else if (message.type === 'processHook') {
|
||||||
this.processHookMessage(workflowHooks, message.data as IProcessMessageDataHook);
|
this.processHookMessage(workflowHooks, message.data as IProcessMessageDataHook);
|
||||||
} else if (message.type === 'timeout') {
|
} else if (message.type === 'timeout') {
|
||||||
// Execution timed out and its process has been terminated
|
// Execution timed out and its process has been terminated
|
||||||
const timeoutError = { message: 'Workflow execution timed out!' } as IExecutionError;
|
const timeoutError = new WorkflowOperationError('Workflow execution timed out!');
|
||||||
|
|
||||||
this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
||||||
} else if (message.type === 'startExecution') {
|
} else if (message.type === 'startExecution') {
|
||||||
|
@ -486,16 +484,12 @@ export class WorkflowRunner {
|
||||||
subprocess.on('exit', (code, signal) => {
|
subprocess.on('exit', (code, signal) => {
|
||||||
if (signal === 'SIGTERM'){
|
if (signal === 'SIGTERM'){
|
||||||
// Execution timed out and its process has been terminated
|
// Execution timed out and its process has been terminated
|
||||||
const timeoutError = {
|
const timeoutError = new WorkflowOperationError('Workflow execution timed out!');
|
||||||
message: 'Workflow execution timed out!',
|
|
||||||
} as IExecutionError;
|
|
||||||
|
|
||||||
this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
||||||
} else if (code !== 0) {
|
} else if (code !== 0) {
|
||||||
// Process did exit with error code, so something went wrong.
|
// Process did exit with error code, so something went wrong.
|
||||||
const executionError = {
|
const executionError = new WorkflowOperationError('Workflow execution process did crash for an unknown reason!');
|
||||||
message: 'Workflow execution process did crash for an unknown reason!',
|
|
||||||
} as IExecutionError;
|
|
||||||
|
|
||||||
this.processError(executionError, startedAt, data.executionMode, executionId);
|
this.processError(executionError, startedAt, data.executionMode, executionId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,9 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ExecutionError,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteData,
|
|
||||||
IExecuteWorkflowInfo,
|
IExecuteWorkflowInfo,
|
||||||
IExecutionError,
|
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeData,
|
INodeTypeData,
|
||||||
|
@ -30,6 +29,7 @@ import {
|
||||||
IWorkflowExecuteHooks,
|
IWorkflowExecuteHooks,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowHooks,
|
WorkflowHooks,
|
||||||
|
WorkflowOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import * as config from '../config';
|
import * as config from '../config';
|
||||||
|
@ -270,7 +270,7 @@ process.on('message', async (message: IProcessMessage) => {
|
||||||
// Workflow started already executing
|
// Workflow started already executing
|
||||||
runData = workflowRunner.workflowExecute.getFullRunData(workflowRunner.startedAt);
|
runData = workflowRunner.workflowExecute.getFullRunData(workflowRunner.startedAt);
|
||||||
|
|
||||||
const timeOutError = message.type === 'timeout' ? { message: 'Workflow execution timed out!' } as IExecutionError : undefined;
|
const timeOutError = message.type === 'timeout' ? new WorkflowOperationError('Workflow execution timed out!') : undefined;
|
||||||
|
|
||||||
// If there is any data send it to parent process, if execution timedout add the error
|
// If there is any data send it to parent process, if execution timedout add the error
|
||||||
await workflowRunner.workflowExecute.processSuccessExecution(workflowRunner.startedAt, workflowRunner.workflow!, timeOutError);
|
await workflowRunner.workflowExecute.processSuccessExecution(workflowRunner.startedAt, workflowRunner.workflow!, timeOutError);
|
||||||
|
@ -301,11 +301,14 @@ process.on('message', async (message: IProcessMessage) => {
|
||||||
workflowRunner.executionIdCallback(message.data.executionId);
|
workflowRunner.executionIdCallback(message.data.executionId);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
// Catch all uncaught errors and forward them to parent process
|
// Catch all uncaught errors and forward them to parent process
|
||||||
const executionError = {
|
const executionError = {
|
||||||
message: error.message,
|
...error,
|
||||||
stack: error.stack,
|
name: error!.name || 'Error',
|
||||||
} as IExecutionError;
|
message: error!.message,
|
||||||
|
stack: error!.stack,
|
||||||
|
} as ExecutionError;
|
||||||
|
|
||||||
await sendToParentProcess('processError', {
|
await sendToParentProcess('processError', {
|
||||||
executionError,
|
executionError,
|
||||||
|
|
|
@ -18,7 +18,6 @@ import {
|
||||||
IWorkflowSettings as IWorkflowSettingsWorkflow,
|
IWorkflowSettings as IWorkflowSettingsWorkflow,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
import { OptionsWithUri, OptionsWithUrl } from 'request';
|
import { OptionsWithUri, OptionsWithUrl } from 'request';
|
||||||
import * as requestPromise from 'request-promise-native';
|
import * as requestPromise from 'request-promise-native';
|
||||||
|
|
||||||
|
@ -26,7 +25,6 @@ interface Constructable<T> {
|
||||||
new(): T;
|
new(): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IProcessMessage {
|
export interface IProcessMessage {
|
||||||
data?: any; // tslint:disable-line:no-any
|
data?: any; // tslint:disable-line:no-any
|
||||||
type: string;
|
type: string;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import {
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
IWorkflowMetadata,
|
IWorkflowMetadata,
|
||||||
NodeHelpers,
|
NodeHelpers,
|
||||||
|
NodeOperationError,
|
||||||
NodeParameterValue,
|
NodeParameterValue,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowActivateMode,
|
WorkflowActivateMode,
|
||||||
|
@ -309,16 +310,16 @@ export function getCredentials(workflow: Workflow, node: INode, type: string, ad
|
||||||
// Get the NodeType as it has the information if the credentials are required
|
// Get the NodeType as it has the information if the credentials are required
|
||||||
const nodeType = workflow.nodeTypes.getByName(node.type);
|
const nodeType = workflow.nodeTypes.getByName(node.type);
|
||||||
if (nodeType === undefined) {
|
if (nodeType === undefined) {
|
||||||
throw new Error(`Node type "${node.type}" is not known so can not get credentials!`);
|
throw new NodeOperationError(node, `Node type "${node.type}" is not known so can not get credentials!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeType.description.credentials === undefined) {
|
if (nodeType.description.credentials === undefined) {
|
||||||
throw new Error(`Node type "${node.type}" does not have any credentials defined!`);
|
throw new NodeOperationError(node, `Node type "${node.type}" does not have any credentials defined!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeCredentialDescription = nodeType.description.credentials.find((credentialTypeDescription) => credentialTypeDescription.name === type);
|
const nodeCredentialDescription = nodeType.description.credentials.find((credentialTypeDescription) => credentialTypeDescription.name === type);
|
||||||
if (nodeCredentialDescription === undefined) {
|
if (nodeCredentialDescription === undefined) {
|
||||||
throw new Error(`Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
|
throw new NodeOperationError(node, `Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NodeHelpers.displayParameter(additionalData.currentNodeParameters || node.parameters, nodeCredentialDescription, node.parameters) === false) {
|
if (NodeHelpers.displayParameter(additionalData.currentNodeParameters || node.parameters, nodeCredentialDescription, node.parameters) === false) {
|
||||||
|
@ -333,10 +334,10 @@ export function getCredentials(workflow: Workflow, node: INode, type: string, ad
|
||||||
if (nodeCredentialDescription.required === true) {
|
if (nodeCredentialDescription.required === true) {
|
||||||
// Credentials are required so error
|
// Credentials are required so error
|
||||||
if (!node.credentials) {
|
if (!node.credentials) {
|
||||||
throw new Error('Node does not have any credentials set!');
|
throw new NodeOperationError(node,'Node does not have any credentials set!');
|
||||||
}
|
}
|
||||||
if (!node.credentials[type]) {
|
if (!node.credentials[type]) {
|
||||||
throw new Error(`Node does not have any credentials set for "${type}"!`);
|
throw new NodeOperationError(node,`Node does not have any credentials set for "${type}"!`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Credentials are not required so resolve with undefined
|
// Credentials are not required so resolve with undefined
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as PCancelable from 'p-cancelable';
|
import * as PCancelable from 'p-cancelable';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ExecutionError,
|
||||||
IConnection,
|
IConnection,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteData,
|
IExecuteData,
|
||||||
IExecutionError,
|
|
||||||
INode,
|
INode,
|
||||||
INodeConnections,
|
INodeConnections,
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowExecuteMode,
|
WorkflowExecuteMode,
|
||||||
|
WorkflowOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import {
|
import {
|
||||||
NodeExecuteFunctions,
|
NodeExecuteFunctions,
|
||||||
|
@ -490,7 +491,7 @@ export class WorkflowExecute {
|
||||||
|
|
||||||
// Variables which hold temporary data for each node-execution
|
// Variables which hold temporary data for each node-execution
|
||||||
let executionData: IExecuteData;
|
let executionData: IExecuteData;
|
||||||
let executionError: IExecutionError | undefined;
|
let executionError: ExecutionError | undefined;
|
||||||
let executionNode: INode;
|
let executionNode: INode;
|
||||||
let nodeSuccessData: INodeExecutionData[][] | null | undefined;
|
let nodeSuccessData: INodeExecutionData[][] | null | undefined;
|
||||||
let runIndex: number;
|
let runIndex: number;
|
||||||
|
@ -517,8 +518,10 @@ export class WorkflowExecute {
|
||||||
try {
|
try {
|
||||||
await this.executeHook('workflowExecuteBefore', [workflow]);
|
await this.executeHook('workflowExecuteBefore', [workflow]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
// Set the error that it can be saved correctly
|
// Set the error that it can be saved correctly
|
||||||
executionError = {
|
executionError = {
|
||||||
|
...error,
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
};
|
};
|
||||||
|
@ -683,9 +686,11 @@ export class WorkflowExecute {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
||||||
|
|
||||||
executionError = {
|
executionError = {
|
||||||
|
...error,
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
};
|
};
|
||||||
|
@ -784,7 +789,7 @@ export class WorkflowExecute {
|
||||||
})()
|
})()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
if (gotCancel && executionError === undefined) {
|
if (gotCancel && executionError === undefined) {
|
||||||
return this.processSuccessExecution(startedAt, workflow, { message: 'Workflow has been canceled!' } as IExecutionError);
|
return this.processSuccessExecution(startedAt, workflow, new WorkflowOperationError('Workflow has been canceled!'));
|
||||||
}
|
}
|
||||||
return this.processSuccessExecution(startedAt, workflow, executionError);
|
return this.processSuccessExecution(startedAt, workflow, executionError);
|
||||||
})
|
})
|
||||||
|
@ -792,6 +797,7 @@ export class WorkflowExecute {
|
||||||
const fullRunData = this.getFullRunData(startedAt);
|
const fullRunData = this.getFullRunData(startedAt);
|
||||||
|
|
||||||
fullRunData.data.resultData.error = {
|
fullRunData.data.resultData.error = {
|
||||||
|
...error,
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
};
|
};
|
||||||
|
@ -815,7 +821,7 @@ export class WorkflowExecute {
|
||||||
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async processSuccessExecution(startedAt: Date, workflow: Workflow, executionError?: IExecutionError): PCancelable<IRun> {
|
async processSuccessExecution(startedAt: Date, workflow: Workflow, executionError?: ExecutionError): PCancelable<IRun> {
|
||||||
const fullRunData = this.getFullRunData(startedAt);
|
const fullRunData = this.getFullRunData(startedAt);
|
||||||
|
|
||||||
if (executionError !== undefined) {
|
if (executionError !== undefined) {
|
||||||
|
|
177
packages/editor-ui/src/components/Error/NodeViewError.vue
Normal file
177
packages/editor-ui/src/components/Error/NodeViewError.vue
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="error-header">
|
||||||
|
<div class="error-message">ERROR: {{error.message}}</div>
|
||||||
|
<div class="error-description" v-if="error.description">{{error.description}}</div>
|
||||||
|
</div>
|
||||||
|
<details>
|
||||||
|
<summary class="error-details__summary">
|
||||||
|
<font-awesome-icon class="error-details__icon" icon="angle-right" /> Details
|
||||||
|
</summary>
|
||||||
|
<div class="error-details__content">
|
||||||
|
<div v-if="error.timestamp">
|
||||||
|
<el-card class="box-card" shadow="never">
|
||||||
|
<div slot="header" class="clearfix box-card__title">
|
||||||
|
<span>Time</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{new Date(error.timestamp).toLocaleString()}}
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div v-if="error.httpCode">
|
||||||
|
<el-card class="box-card" shadow="never">
|
||||||
|
<div slot="header" class="clearfix box-card__title">
|
||||||
|
<span>HTTP-Code</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{error.httpCode}}
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div v-if="error.cause">
|
||||||
|
<el-card class="box-card" shadow="never">
|
||||||
|
<div slot="header" class="clearfix box-card__title">
|
||||||
|
<span>Cause</span>
|
||||||
|
<br>
|
||||||
|
<span class="box-card__subtitle">Data below may contain sensitive information. Proceed with caution when sharing.</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button class="copy-button" @click="copyCause" circle type="text" title="Copy to clipboard">
|
||||||
|
<font-awesome-icon icon="copy" />
|
||||||
|
</el-button>
|
||||||
|
<vue-json-pretty
|
||||||
|
:data="error.cause"
|
||||||
|
:deep="3"
|
||||||
|
:showLength="true"
|
||||||
|
selectableType="single"
|
||||||
|
path="error"
|
||||||
|
class="json-data"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div v-if="error.stack">
|
||||||
|
<el-card class="box-card" shadow="never">
|
||||||
|
<div slot="header" class="clearfix box-card__title">
|
||||||
|
<span>Stack</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<pre><code>{{error.stack}}</code></pre>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
//@ts-ignore
|
||||||
|
import VueJsonPretty from 'vue-json-pretty';
|
||||||
|
import { copyPaste } from '@/components/mixins/copyPaste';
|
||||||
|
import { showMessage } from '@/components/mixins/showMessage';
|
||||||
|
import mixins from 'vue-typed-mixins';
|
||||||
|
|
||||||
|
|
||||||
|
export default mixins(
|
||||||
|
copyPaste,
|
||||||
|
showMessage,
|
||||||
|
).extend({
|
||||||
|
name: 'NodeErrorView',
|
||||||
|
props: [
|
||||||
|
'error',
|
||||||
|
],
|
||||||
|
components: {
|
||||||
|
VueJsonPretty,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
copyCause() {
|
||||||
|
this.copyToClipboard(JSON.stringify(this.error.cause));
|
||||||
|
this.copySuccess();
|
||||||
|
},
|
||||||
|
copySuccess() {
|
||||||
|
this.$showMessage({
|
||||||
|
title: 'Copied to clipboard',
|
||||||
|
message: '',
|
||||||
|
type: 'info',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
.error-header {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: #ff0000;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-description {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-details__summary {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-details__icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
details > summary {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
details > summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] {
|
||||||
|
.error-details__icon {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-details__content {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-divider__text {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card {
|
||||||
|
margin-top: 1em;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card__title {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card__subtitle {
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
right: 50px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -81,8 +81,7 @@
|
||||||
<div class="data-display-content">
|
<div class="data-display-content">
|
||||||
<span v-if="node && workflowRunData !== null && workflowRunData.hasOwnProperty(node.name)">
|
<span v-if="node && workflowRunData !== null && workflowRunData.hasOwnProperty(node.name)">
|
||||||
<div v-if="workflowRunData[node.name][runIndex].error" class="error-display">
|
<div v-if="workflowRunData[node.name][runIndex].error" class="error-display">
|
||||||
<div class="error-message">ERROR: {{workflowRunData[node.name][runIndex].error.message}}</div>
|
<NodeErrorView :error="workflowRunData[node.name][runIndex].error" />
|
||||||
<pre><code>{{workflowRunData[node.name][runIndex].error.stack}}</code></pre>
|
|
||||||
</div>
|
</div>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<div v-if="showData === false" class="to-much-data">
|
<div v-if="showData === false" class="to-much-data">
|
||||||
|
@ -226,6 +225,7 @@ import {
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
|
|
||||||
import BinaryDataDisplay from '@/components/BinaryDataDisplay.vue';
|
import BinaryDataDisplay from '@/components/BinaryDataDisplay.vue';
|
||||||
|
import NodeErrorView from '@/components/Error/NodeViewError.vue';
|
||||||
|
|
||||||
import { copyPaste } from '@/components/mixins/copyPaste';
|
import { copyPaste } from '@/components/mixins/copyPaste';
|
||||||
import { genericHelpers } from '@/components/mixins/genericHelpers';
|
import { genericHelpers } from '@/components/mixins/genericHelpers';
|
||||||
|
@ -247,6 +247,7 @@ export default mixins(
|
||||||
name: 'RunData',
|
name: 'RunData',
|
||||||
components: {
|
components: {
|
||||||
BinaryDataDisplay,
|
BinaryDataDisplay,
|
||||||
|
NodeErrorView,
|
||||||
VueJsonPretty,
|
VueJsonPretty,
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
@ -739,13 +740,6 @@ export default mixins(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-display {
|
|
||||||
.error-message {
|
|
||||||
color: #ff0000;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
|
@ -207,8 +207,19 @@ export const pushConnection = mixins(
|
||||||
if (runDataExecuted.finished !== true) {
|
if (runDataExecuted.finished !== true) {
|
||||||
// There was a problem with executing the workflow
|
// There was a problem with executing the workflow
|
||||||
let errorMessage = 'There was a problem executing the workflow!';
|
let errorMessage = 'There was a problem executing the workflow!';
|
||||||
|
|
||||||
if (runDataExecuted.data.resultData.error && runDataExecuted.data.resultData.error.message) {
|
if (runDataExecuted.data.resultData.error && runDataExecuted.data.resultData.error.message) {
|
||||||
errorMessage = `There was a problem executing the workflow:<br /><strong>"${runDataExecuted.data.resultData.error.message}"</strong>`;
|
let nodeName: string | undefined;
|
||||||
|
if (runDataExecuted.data.resultData.error.node) {
|
||||||
|
nodeName = typeof runDataExecuted.data.resultData.error.node === 'string'
|
||||||
|
? runDataExecuted.data.resultData.error.node
|
||||||
|
: runDataExecuted.data.resultData.error.node.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const receivedError = nodeName
|
||||||
|
? `${nodeName}: ${runDataExecuted.data.resultData.error.message}`
|
||||||
|
: runDataExecuted.data.resultData.error.message;
|
||||||
|
errorMessage = `There was a problem executing the workflow:<br /><strong>"${receivedError}"</strong>`;
|
||||||
}
|
}
|
||||||
this.$titleSet(workflow.name, 'ERROR');
|
this.$titleSet(workflow.name, 'ERROR');
|
||||||
this.$showMessage({
|
this.$showMessage({
|
||||||
|
|
|
@ -459,6 +459,10 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-notification__content {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Custom scrollbar
|
// Custom scrollbar
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -431,7 +432,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
addAdditionalFields(body.contact as IDataObject, updateFields);
|
addAdditionalFields(body.contact as IDataObject, updateFields);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'account') {
|
} else if (resource === 'account') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -512,7 +513,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
addAdditionalFields(body.account as IDataObject, updateFields);
|
addAdditionalFields(body.account as IDataObject, updateFields);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'accountContact') {
|
} else if (resource === 'accountContact') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -562,7 +563,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/accountContacts/${accountContactId}`;
|
endpoint = `/api/3/accountContacts/${accountContactId}`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'contactTag') {
|
} else if (resource === 'contactTag') {
|
||||||
if (operation === 'add') {
|
if (operation === 'add') {
|
||||||
|
@ -592,7 +593,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/contactTags/${contactTagId}`;
|
endpoint = `/api/3/contactTags/${contactTagId}`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'contactList') {
|
} else if (resource === 'contactList') {
|
||||||
if (operation === 'add') {
|
if (operation === 'add') {
|
||||||
|
@ -630,7 +631,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
dataKey = 'contacts';
|
dataKey = 'contacts';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'list') {
|
} else if (resource === 'list') {
|
||||||
if (operation === 'getAll') {
|
if (operation === 'getAll') {
|
||||||
|
@ -732,7 +733,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
addAdditionalFields(body.tag as IDataObject, updateFields);
|
addAdditionalFields(body.tag as IDataObject, updateFields);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'deal') {
|
} else if (resource === 'deal') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -851,7 +852,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/deals/${dealId}/notes/${dealNoteId}`;
|
endpoint = `/api/3/deals/${dealId}/notes/${dealNoteId}`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'connection') {
|
} else if (resource === 'connection') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -926,7 +927,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/connections`;
|
endpoint = `/api/3/connections`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'ecommerceOrder') {
|
} else if (resource === 'ecommerceOrder') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -1024,7 +1025,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/ecomOrders`;
|
endpoint = `/api/3/ecomOrders`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'ecommerceCustomer') {
|
} else if (resource === 'ecommerceCustomer') {
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -1114,7 +1115,7 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/ecomCustomers`;
|
endpoint = `/api/3/ecomCustomers`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
} else if (resource === 'ecommerceOrderProducts') {
|
} else if (resource === 'ecommerceOrderProducts') {
|
||||||
if (operation === 'getByProductId') {
|
if (operation === 'getByProductId') {
|
||||||
|
@ -1160,11 +1161,11 @@ export class ActiveCampaign implements INodeType {
|
||||||
endpoint = `/api/3/ecomOrderProducts`;
|
endpoint = `/api/3/ecomOrderProducts`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The resource "${resource}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let responseData;
|
let responseData;
|
||||||
|
|
|
@ -116,7 +116,7 @@ export class ActiveCampaignTrigger implements INodeType {
|
||||||
const endpoint = `/api/3/webhooks/${webhookData.webhookId}`;
|
const endpoint = `/api/3/webhooks/${webhookData.webhookId}`;
|
||||||
try {
|
try {
|
||||||
await activeCampaignApiRequest.call(this, 'GET', endpoint, {});
|
await activeCampaignApiRequest.call(this, 'GET', endpoint, {});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject, ILoadOptionsFunctions, INodeProperties,
|
IDataObject, ILoadOptionsFunctions, INodeProperties, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { OptionsWithUri } from 'request';
|
import { OptionsWithUri } from 'request';
|
||||||
|
@ -28,7 +28,7 @@ export interface IProduct {
|
||||||
export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKey?: string): Promise<any> { // tslint:disable-line:no-any
|
export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKey?: string): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('activeCampaignApi');
|
const credentials = this.getCredentials('activeCampaignApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query === undefined) {
|
if (query === undefined) {
|
||||||
|
@ -53,7 +53,7 @@ export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFu
|
||||||
const responseData = await this.helpers.request!(options);
|
const responseData = await this.helpers.request!(options);
|
||||||
|
|
||||||
if (responseData.success === false) {
|
if (responseData.success === false) {
|
||||||
throw new Error(`ActiveCampaign error response: ${responseData.error} (${responseData.error_info})`);
|
throw new NodeApiError(this.getNode(), responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataKey === undefined) {
|
if (dataKey === undefined) {
|
||||||
|
@ -63,13 +63,7 @@ export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFu
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 403) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The ActiveCampaign credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function acuitySchedulingApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function acuitySchedulingApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const authenticationMethod = this.getNodeParameter('authentication', 0);
|
const authenticationMethod = this.getNodeParameter('authentication', 0);
|
||||||
|
@ -27,7 +27,7 @@ export async function acuitySchedulingApiRequest(this: IHookFunctions | IExecute
|
||||||
if (authenticationMethod === 'apiKey') {
|
if (authenticationMethod === 'apiKey') {
|
||||||
const credentials = this.getCredentials('acuitySchedulingApi');
|
const credentials = this.getCredentials('acuitySchedulingApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.auth = {
|
options.auth = {
|
||||||
|
@ -42,6 +42,6 @@ export async function acuitySchedulingApiRequest(this: IHookFunctions | IExecute
|
||||||
return await this.helpers.requestOAuth2!.call(this, 'acuitySchedulingOAuth2Api', options, true);
|
return await this.helpers.requestOAuth2!.call(this, 'acuitySchedulingOAuth2Api', options, true);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error('Acuity Scheduling Error: ' + error.message);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
IWebhookResponseData,
|
IWebhookResponseData,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -187,7 +188,7 @@ export class AffinityTrigger implements INodeType {
|
||||||
const webhookUrl = this.getNodeWebhookUrl('default') as string;
|
const webhookUrl = this.getNodeWebhookUrl('default') as string;
|
||||||
|
|
||||||
if (webhookUrl.includes('%20')) {
|
if (webhookUrl.includes('%20')) {
|
||||||
throw new Error('The name of the Affinity Trigger Node is not allowed to contain any spaces!');
|
throw new NodeOperationError(this.getNode(), 'The name of the Affinity Trigger Node is not allowed to contain any spaces!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const events = this.getNodeParameter('events') as string[];
|
const events = this.getNodeParameter('events') as string[];
|
||||||
|
|
|
@ -12,6 +12,8 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function affinityApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function affinityApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -19,7 +21,7 @@ export async function affinityApiRequest(this: IExecuteFunctions | IWebhookFunct
|
||||||
const credentials = this.getCredentials('affinityApi');
|
const credentials = this.getCredentials('affinityApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiKey = `:${credentials.apiKey}`;
|
const apiKey = `:${credentials.apiKey}`;
|
||||||
|
@ -47,11 +49,7 @@ export async function affinityApiRequest(this: IExecuteFunctions | IWebhookFunct
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
const errorMessage = error.response.body.message || error.response.body.description || error.message;
|
|
||||||
throw new Error(`Affinity error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -149,7 +150,7 @@ export class AgileCrm implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +306,7 @@ export class AgileCrm implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -483,7 +484,7 @@ export class AgileCrm implements INodeType {
|
||||||
if (validateJSON(additionalFieldsJson) !== undefined) {
|
if (validateJSON(additionalFieldsJson) !== undefined) {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +526,7 @@ export class AgileCrm implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { IContactUpdate } from './ContactInterface';
|
import { IContactUpdate } from './ContactInterface';
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`AgileCRM error response: ${error.message}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -114,9 +114,9 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (successfulUpdates.length === 0) {
|
if (successfulUpdates.length === 0) {
|
||||||
throw new Error(`AgileCRM error response: ${error.message}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Not all properties updated. Updated properties: ${successfulUpdates.join(', ')} \n \nAgileCRM error response: ${error.message}`);
|
throw new NodeApiError(this.getNode(), error, { message: `Not all properties updated. Updated properties: ${successfulUpdates.join(', ')}`, description: error.message, httpCode: error.statusCode });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -636,7 +637,7 @@ export class Airtable implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [this.helpers.returnJsonArray(returnData)];
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -170,7 +171,7 @@ export class AirtableTrigger implements INodeType {
|
||||||
|
|
||||||
if (Array.isArray(records) && records.length) {
|
if (Array.isArray(records) && records.length) {
|
||||||
if (this.getMode() === 'manual' && records[0].fields[triggerField] === undefined) {
|
if (this.getMode() === 'manual' && records[0].fields[triggerField] === undefined) {
|
||||||
throw new Error(`The Field "${triggerField}" does not exist.`);
|
throw new NodeOperationError(this.getNode(), `The Field "${triggerField}" does not exist.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadAttachments === true) {
|
if (downloadAttachments === true) {
|
||||||
|
|
|
@ -13,6 +13,8 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
IPollFunctions,
|
IPollFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ export async function apiRequest(this: IHookFunctions | IExecuteFunctions | ILoa
|
||||||
const credentials = this.getCredentials('airtableApi');
|
const credentials = this.getCredentials('airtableApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
query = query || {};
|
query = query || {};
|
||||||
|
@ -73,23 +75,7 @@ export async function apiRequest(this: IHookFunctions | IExecuteFunctions | ILoa
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Airtable credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.response && error.response.body && error.response.body.error) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
|
|
||||||
const airtableError = error.response.body.error;
|
|
||||||
|
|
||||||
if (airtableError.type && airtableError.message) {
|
|
||||||
throw new Error(`Airtable error response [${airtableError.type}]: ${airtableError.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected error data did not get returned so rhow the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export class Amqp implements INodeType {
|
export class Amqp implements INodeType {
|
||||||
|
@ -98,7 +99,7 @@ export class Amqp implements INodeType {
|
||||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
const credentials = this.getCredentials('amqp');
|
const credentials = this.getCredentials('amqp');
|
||||||
if (!credentials) {
|
if (!credentials) {
|
||||||
throw new Error('Credentials are mandatory!');
|
throw new NodeOperationError(this.getNode(), 'Credentials are mandatory!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const sink = this.getNodeParameter('sink', 0, '') as string;
|
const sink = this.getNodeParameter('sink', 0, '') as string;
|
||||||
|
@ -116,7 +117,7 @@ export class Amqp implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink === '') {
|
if (sink === '') {
|
||||||
throw new Error('Queue or Topic required!');
|
throw new NodeOperationError(this.getNode(), 'Queue or Topic required!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = create_container();
|
const container = create_container();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
ITriggerResponse,
|
ITriggerResponse,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ export class AmqpTrigger implements INodeType {
|
||||||
|
|
||||||
const credentials = this.getCredentials('amqp');
|
const credentials = this.getCredentials('amqp');
|
||||||
if (!credentials) {
|
if (!credentials) {
|
||||||
throw new Error('Credentials are mandatory!');
|
throw new NodeOperationError(this.getNode(), 'Credentials are mandatory!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const sink = this.getNodeParameter('sink', '') as string;
|
const sink = this.getNodeParameter('sink', '') as string;
|
||||||
|
@ -146,7 +147,7 @@ export class AmqpTrigger implements INodeType {
|
||||||
const containerReconnectLimit = options.reconnectLimit as number || 50;
|
const containerReconnectLimit = options.reconnectLimit as number || 50;
|
||||||
|
|
||||||
if (sink === '') {
|
if (sink === '') {
|
||||||
throw new Error('Queue or Topic required!');
|
throw new NodeOperationError(this.getNode(), 'Queue or Topic required!');
|
||||||
}
|
}
|
||||||
|
|
||||||
let durable = false;
|
let durable = false;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -466,7 +467,7 @@ export class ApiTemplateIo implements INodeType {
|
||||||
if (overrideJson !== '') {
|
if (overrideJson !== '') {
|
||||||
const data = validateJSON(overrideJson);
|
const data = validateJSON(overrideJson);
|
||||||
if (data === undefined) {
|
if (data === undefined) {
|
||||||
throw new Error('A valid JSON must be provided.');
|
throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.');
|
||||||
}
|
}
|
||||||
body.overrides = data;
|
body.overrides = data;
|
||||||
}
|
}
|
||||||
|
@ -523,14 +524,14 @@ export class ApiTemplateIo implements INodeType {
|
||||||
if (jsonParameters === false) {
|
if (jsonParameters === false) {
|
||||||
const properties = (this.getNodeParameter('propertiesUi', i) as IDataObject || {}).propertyValues as IDataObject[] || [];
|
const properties = (this.getNodeParameter('propertiesUi', i) as IDataObject || {}).propertyValues as IDataObject[] || [];
|
||||||
if (properties.length === 0) {
|
if (properties.length === 0) {
|
||||||
throw new Error('The parameter properties cannot be empty');
|
throw new NodeOperationError(this.getNode(), 'The parameter properties cannot be empty');
|
||||||
}
|
}
|
||||||
data = properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {});
|
data = properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {});
|
||||||
} else {
|
} else {
|
||||||
const propertiesJson = this.getNodeParameter('propertiesJson', i) as string;
|
const propertiesJson = this.getNodeParameter('propertiesJson', i) as string;
|
||||||
data = validateJSON(propertiesJson);
|
data = validateJSON(propertiesJson);
|
||||||
if (data === undefined) {
|
if (data === undefined) {
|
||||||
throw new Error('A valid JSON must be provided.');
|
throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function apiTemplateIoApiRequest(
|
export async function apiTemplateIoApiRequest(
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
|
@ -42,14 +43,11 @@ export async function apiTemplateIoApiRequest(
|
||||||
try {
|
try {
|
||||||
const response = await this.helpers.request!(options);
|
const response = await this.helpers.request!(options);
|
||||||
if (response.status === 'error') {
|
if (response.status === 'error') {
|
||||||
throw new Error(response.message);
|
throw new NodeApiError(this.getNode(), response.message);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.response?.body?.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
throw new Error(`APITemplate.io error response [${error.statusCode}]: ${error.response.body.message}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -1639,7 +1641,7 @@ export class Asana implements INodeType {
|
||||||
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
if (responseData.data === undefined) {
|
if (responseData.data === undefined) {
|
||||||
throw new Error('No data got returned');
|
throw new NodeApiError(this.getNode(), responseData, { message: 'No data got returned' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
@ -1674,7 +1676,7 @@ export class Asana implements INodeType {
|
||||||
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
if (responseData.data === undefined) {
|
if (responseData.data === undefined) {
|
||||||
throw new Error('No data got returned');
|
throw new NodeApiError(this.getNode(), responseData, { message: 'No data got returned' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
@ -1711,7 +1713,7 @@ export class Asana implements INodeType {
|
||||||
// to retrieve the teams from an organization just work with workspaces that are an organization
|
// to retrieve the teams from an organization just work with workspaces that are an organization
|
||||||
|
|
||||||
if (workspace.is_organization === false) {
|
if (workspace.is_organization === false) {
|
||||||
throw Error('To filter by team, the workspace selected has to be an organization');
|
throw new NodeOperationError(this.getNode(), 'To filter by team, the workspace selected has to be an organization');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/organizations/${workspaceId}/teams`;
|
const endpoint = `/organizations/${workspaceId}/teams`;
|
||||||
|
@ -1750,15 +1752,15 @@ export class Asana implements INodeType {
|
||||||
let taskData;
|
let taskData;
|
||||||
try {
|
try {
|
||||||
taskData = await asanaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {});
|
taskData = await asanaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
throw new Error(`Could not find task with id "${taskId}" so tags could not be loaded.`);
|
throw new NodeApiError(this.getNode(), error, { message: `Could not find task with id "${taskId}" so tags could not be loaded.` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const workspace = taskData.data.workspace.gid;
|
const workspace = taskData.data.workspace.gid;
|
||||||
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {}, { workspace });
|
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {}, { workspace });
|
||||||
|
|
||||||
if (responseData.data === undefined) {
|
if (responseData.data === undefined) {
|
||||||
throw new Error('No data got returned');
|
throw new NodeApiError(this.getNode(), responseData, { message: 'No data got returned' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
@ -1790,7 +1792,7 @@ export class Asana implements INodeType {
|
||||||
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
const responseData = await asanaApiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
if (responseData.data === undefined) {
|
if (responseData.data === undefined) {
|
||||||
throw new Error('No data got returned');
|
throw new NodeApiError(this.getNode(), responseData, { message: 'No data got returned' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
IWebhookResponseData,
|
IWebhookResponseData,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -155,7 +156,7 @@ export class AsanaTrigger implements INodeType {
|
||||||
const webhookUrl = this.getNodeWebhookUrl('default') as string;
|
const webhookUrl = this.getNodeWebhookUrl('default') as string;
|
||||||
|
|
||||||
if (webhookUrl.includes('%20')) {
|
if (webhookUrl.includes('%20')) {
|
||||||
throw new Error('The name of the Asana Trigger Node is not allowed to contain any spaces!');
|
throw new NodeOperationError(this.getNode(), 'The name of the Asana Trigger Node is not allowed to contain any spaces!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource = this.getNodeParameter('resource') as string;
|
const resource = this.getNodeParameter('resource') as string;
|
||||||
|
@ -189,7 +190,7 @@ export class AsanaTrigger implements INodeType {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await asanaApiRequest.call(this, 'DELETE', endpoint, body);
|
await asanaApiRequest.call(this, 'DELETE', endpoint, body);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -43,7 +45,7 @@ export async function asanaApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
const credentials = this.getCredentials('asanaApi');
|
const credentials = this.getCredentials('asanaApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.headers!['Authorization'] = `Bearer ${credentials.accessToken}`;
|
options.headers!['Authorization'] = `Bearer ${credentials.accessToken}`;
|
||||||
|
@ -54,25 +56,7 @@ export async function asanaApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
return await this.helpers.requestOAuth2.call(this, 'asanaOAuth2Api', options);
|
return await this.helpers.requestOAuth2.call(this, 'asanaOAuth2Api', options);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Asana credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.response && error.response.body && error.response.body.errors) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
const errorMessages = error.response.body.errors.map((errorData: { message: string }) => {
|
|
||||||
return errorData.message;
|
|
||||||
});
|
|
||||||
throw new Error(`Asana error response [${error.statusCode}]: ${errorMessages.join(' | ')}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function automizyApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, path: string, body: any = {}, qs: IDataObject = {}, option = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function automizyApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, path: string, body: any = {}, qs: IDataObject = {}, option = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -40,14 +40,7 @@ export async function automizyApiRequest(this: IExecuteFunctions | IExecuteSingl
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
return await this.helpers.request.call(this, options);
|
return await this.helpers.request.call(this, options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response && error.response.body) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
|
||||||
throw new Error(
|
|
||||||
`Automizy error response [${error.statusCode}]: ${error.response.body.title}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function autopilotApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function autopilotApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -42,11 +43,7 @@ export async function autopilotApiRequest(this: IExecuteFunctions | IWebhookFunc
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
const errorMessage = error.response.body.message || error.response.body.description || error.message;
|
|
||||||
throw new Error(`Autopilot error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { awsApiRequestREST } from './GenericFunctions';
|
import { awsApiRequestREST } from './GenericFunctions';
|
||||||
|
@ -130,13 +132,7 @@ export class AwsLambda implements INodeType {
|
||||||
loadOptions: {
|
loadOptions: {
|
||||||
async getFunctions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getFunctions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const data = await awsApiRequestREST.call(this, 'lambda', 'GET', '/2015-03-31/functions/');
|
||||||
let data;
|
|
||||||
try {
|
|
||||||
data = await awsApiRequestREST.call(this, 'lambda', 'GET', '/2015-03-31/functions/');
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`AWS Error: ${err}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const func of data.Functions!) {
|
for (const func of data.Functions!) {
|
||||||
returnData.push({
|
returnData.push({
|
||||||
|
@ -162,22 +158,17 @@ export class AwsLambda implements INodeType {
|
||||||
Qualifier: this.getNodeParameter('qualifier', i) as string,
|
Qualifier: this.getNodeParameter('qualifier', i) as string,
|
||||||
};
|
};
|
||||||
|
|
||||||
let responseData;
|
const responseData = await awsApiRequestREST.call(
|
||||||
try {
|
this,
|
||||||
responseData = await awsApiRequestREST.call(
|
'lambda',
|
||||||
this,
|
'POST',
|
||||||
'lambda',
|
`/2015-03-31/functions/${params.FunctionName}/invocations?Qualifier=${params.Qualifier}`,
|
||||||
'POST',
|
params.Payload,
|
||||||
`/2015-03-31/functions/${params.FunctionName}/invocations?Qualifier=${params.Qualifier}`,
|
{
|
||||||
params.Payload,
|
'X-Amz-Invocation-Type': params.InvocationType,
|
||||||
{
|
'Content-Type': 'application/x-amz-json-1.0',
|
||||||
'X-Amz-Invocation-Type': params.InvocationType,
|
},
|
||||||
'Content-Type': 'application/x-amz-json-1.0',
|
);
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`AWS Error: ${err}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseData !== null && responseData.errorMessage !== undefined) {
|
if (responseData !== null && responseData.errorMessage !== undefined) {
|
||||||
let errorMessage = responseData.errorMessage;
|
let errorMessage = responseData.errorMessage;
|
||||||
|
@ -186,7 +177,7 @@ export class AwsLambda implements INodeType {
|
||||||
errorMessage += `\n\nStack trace:\n${responseData.stackTrace}`;
|
errorMessage += `\n\nStack trace:\n${responseData.stackTrace}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(errorMessage);
|
throw new NodeApiError(this.getNode(), responseData);
|
||||||
} else {
|
} else {
|
||||||
returnData.push({
|
returnData.push({
|
||||||
result: responseData,
|
result: responseData,
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { awsApiRequestSOAP } from './GenericFunctions';
|
import { awsApiRequestSOAP } from './GenericFunctions';
|
||||||
|
@ -107,12 +109,7 @@ export class AwsSns implements INodeType {
|
||||||
// select them easily
|
// select them easily
|
||||||
async getTopics(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getTopics(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
let data;
|
const data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListTopics');
|
||||||
try {
|
|
||||||
data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListTopics');
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`AWS Error: ${err}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let topics = data.ListTopicsResponse.ListTopicsResult.Topics.member;
|
let topics = data.ListTopicsResponse.ListTopicsResult.Topics.member;
|
||||||
|
|
||||||
|
@ -149,12 +146,8 @@ export class AwsSns implements INodeType {
|
||||||
'Message=' + this.getNodeParameter('message', i) as string,
|
'Message=' + this.getNodeParameter('message', i) as string,
|
||||||
];
|
];
|
||||||
|
|
||||||
let responseData;
|
|
||||||
try {
|
const responseData = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Publish&' + params.join('&'));
|
||||||
responseData = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Publish&' + params.join('&'));
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`AWS Error: ${err}`);
|
|
||||||
}
|
|
||||||
returnData.push({MessageId: responseData.PublishResponse.PublishResult.MessageId} as IDataObject);
|
returnData.push({MessageId: responseData.PublishResponse.PublishResult.MessageId} as IDataObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
IWebhookResponseData,
|
IWebhookResponseData,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -68,12 +70,7 @@ export class AwsSnsTrigger implements INodeType {
|
||||||
// select them easily
|
// select them easily
|
||||||
async getTopics(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getTopics(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
let data;
|
const data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListTopics');
|
||||||
try {
|
|
||||||
data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListTopics');
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`AWS Error: ${err}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let topics = data.ListTopicsResponse.ListTopicsResult.Topics.member;
|
let topics = data.ListTopicsResponse.ListTopicsResult.Topics.member;
|
||||||
|
|
||||||
|
@ -134,7 +131,7 @@ export class AwsSnsTrigger implements INodeType {
|
||||||
const topic = this.getNodeParameter('topic') as string;
|
const topic = this.getNodeParameter('topic') as string;
|
||||||
|
|
||||||
if (webhookUrl.includes('%20')) {
|
if (webhookUrl.includes('%20')) {
|
||||||
throw new Error('The name of the SNS Trigger Node is not allowed to contain any spaces!');
|
throw new NodeOperationError(this.getNode(), 'The name of the SNS Trigger Node is not allowed to contain any spaces!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = [
|
const params = [
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string {
|
function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string {
|
||||||
|
@ -40,7 +40,7 @@ function getEndpointForService(service: string, credentials: ICredentialDataDecr
|
||||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('aws');
|
const credentials = this.getCredentials('aws');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate path and instantiate URL object so it parses correctly query strings
|
// Concatenate path and instantiate URL object so it parses correctly query strings
|
||||||
|
@ -61,17 +61,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
throw new NodeApiError(this.getNode(), error); // no XML parsing needed
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +69,7 @@ export async function awsApiRequestREST(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response);
|
return JSON.parse(response);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +85,7 @@ export async function awsApiRequestSOAP(this: IHookFunctions | IExecuteFunctions
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import { sign } from 'aws4';
|
import { sign } from 'aws4';
|
||||||
import { OptionsWithUri } from 'request';
|
import { OptionsWithUri } from 'request';
|
||||||
import { parseString } from 'xml2js';
|
import { parseString as parseXml } from 'xml2js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
|
@ -11,7 +11,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string {
|
function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string {
|
||||||
|
@ -31,7 +31,7 @@ function getEndpointForService(service: string, credentials: ICredentialDataDecr
|
||||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('aws');
|
const credentials = this.getCredentials('aws');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate path and instantiate URL object so it parses correctly query strings
|
// Concatenate path and instantiate URL object so it parses correctly query strings
|
||||||
|
@ -52,17 +52,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
throw new NodeApiError(this.getNode(), error, { parseXml: true });
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +60,7 @@ export async function awsApiRequestREST(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response);
|
return JSON.parse(response);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,14 +69,14 @@ export async function awsApiRequestSOAP(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
||||||
try {
|
try {
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
parseString(response, { explicitArray: false }, (err, data) => {
|
parseXml(response, { explicitArray: false }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -459,11 +461,11 @@ export class AwsRekognition implements INodeType {
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
||||||
|
|
||||||
if (items[i].binary === undefined) {
|
if (items[i].binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) {
|
if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
||||||
|
@ -494,7 +496,9 @@ export class AwsRekognition implements INodeType {
|
||||||
body.Image.S3Object.Version = additionalFields.version as string;
|
body.Image.S3Object.Version = additionalFields.version as string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData = await awsApiRequestREST.call(this, 'rekognition', 'POST', '', JSON.stringify(body), {}, { 'X-Amz-Target': action, 'Content-Type': 'application/x-amz-json-1.1' });
|
responseData = await awsApiRequestREST.call(this, 'rekognition', 'POST', '', JSON.stringify(body), {}, { 'X-Amz-Target': action, 'Content-Type': 'application/x-amz-json-1.1' });
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -36,7 +38,7 @@ import {
|
||||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string | Buffer | IDataObject, query: IDataObject = {}, headers?: object, option: IDataObject = {}, region?: string): Promise<any> { // tslint:disable-line:no-any
|
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string | Buffer | IDataObject, query: IDataObject = {}, headers?: object, option: IDataObject = {}, region?: string): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('aws');
|
const credentials = this.getCredentials('aws');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = new URL(((credentials.rekognitionEndpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
const endpoint = new URL(((credentials.rekognitionEndpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
||||||
|
@ -59,17 +61,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +69,7 @@ export async function awsApiRequestREST(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, query, headers, options, region);
|
const response = await awsApiRequest.call(this, service, method, path, body, query, headers, options, region);
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response);
|
return JSON.parse(response);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,8 +85,8 @@ export async function awsApiRequestSOAP(this: IHookFunctions | IExecuteFunctions
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return e;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -422,7 +423,7 @@ export class AwsS3 implements INodeType {
|
||||||
const fileName = fileKey.split('/')[fileKey.split('/').length - 1];
|
const fileName = fileKey.split('/')[fileKey.split('/').length - 1];
|
||||||
|
|
||||||
if (fileKey.substring(fileKey.length - 1) === '/') {
|
if (fileKey.substring(fileKey.length - 1) === '/') {
|
||||||
throw new Error('Downloding a whole directory is not yet supported, please provide a file key');
|
throw new NodeOperationError(this.getNode(), 'Downloding a whole directory is not yet supported, please provide a file key');
|
||||||
}
|
}
|
||||||
|
|
||||||
let region = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' });
|
let region = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' });
|
||||||
|
@ -588,11 +589,11 @@ export class AwsS3 implements INodeType {
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
||||||
|
|
||||||
if (items[i].binary === undefined) {
|
if (items[i].binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) {
|
if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
||||||
|
|
|
@ -26,20 +26,20 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string | Buffer, query: IDataObject = {}, headers?: object, option: IDataObject = {}, region?: string): Promise<any> { // tslint:disable-line:no-any
|
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string | Buffer, query: IDataObject = {}, headers?: object, option: IDataObject = {}, region?: string): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('aws');
|
const credentials = this.getCredentials('aws');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = new URL(((credentials.s3Endpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
const endpoint = new URL(((credentials.s3Endpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
||||||
|
|
||||||
// Sign AWS API request with the user credentials
|
// Sign AWS API request with the user credentials
|
||||||
const signOpts = {headers: headers || {}, host: endpoint.host, method, path: `${endpoint.pathname}?${queryToString(query).replace(/\+/g, '%2B')}`, body};
|
const signOpts = {headers: headers || {}, host: endpoint.host, method, path: `${endpoint.pathname}?${queryToString(query).replace(/\+/g, '%2B')}`, body};
|
||||||
|
|
||||||
|
|
||||||
sign(signOpts, { accessKeyId: `${credentials.accessKeyId}`.trim(), secretAccessKey: `${credentials.secretAccessKey}`.trim()});
|
sign(signOpts, { accessKeyId: `${credentials.accessKeyId}`.trim(), secretAccessKey: `${credentials.secretAccessKey}`.trim()});
|
||||||
|
|
||||||
|
@ -57,17 +57,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
throw new NodeApiError(this.getNode(), error, { parseXml: true });
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +65,7 @@ export async function awsApiRequestREST(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, query, headers, options, region);
|
const response = await awsApiRequest.call(this, service, method, path, body, query, headers, options, region);
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response);
|
return JSON.parse(response);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,8 +81,8 @@ export async function awsApiRequestSOAP(this: IHookFunctions | IExecuteFunctions
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return e;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -1098,7 +1099,7 @@ export class AwsSes implements INodeType {
|
||||||
if (toAddresses.length) {
|
if (toAddresses.length) {
|
||||||
setParameter(params, 'Destination.ToAddresses.member', toAddresses);
|
setParameter(params, 'Destination.ToAddresses.member', toAddresses);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('At least one "To Address" has to be added!');
|
throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (additionalFields.configurationSetName) {
|
if (additionalFields.configurationSetName) {
|
||||||
|
@ -1151,7 +1152,7 @@ export class AwsSes implements INodeType {
|
||||||
if (toAddresses.length) {
|
if (toAddresses.length) {
|
||||||
setParameter(params, 'Destination.ToAddresses.member', toAddresses);
|
setParameter(params, 'Destination.ToAddresses.member', toAddresses);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('At least one "To Address" has to be added!');
|
throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (additionalFields.configurationSetName) {
|
if (additionalFields.configurationSetName) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -32,7 +32,7 @@ import {
|
||||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: string, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('aws');
|
const credentials = this.getCredentials('aws');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = new URL(((credentials.sesEndpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
const endpoint = new URL(((credentials.sesEndpoint as string || '').replace('{region}', credentials.region as string) || `https://${service}.${credentials.region}.amazonaws.com`) + path);
|
||||||
|
@ -52,17 +52,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
throw new NodeApiError(this.getNode(), error, { parseXml: true });
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
|
||||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
|
||||||
throw new Error('The AWS credentials are not valid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +60,7 @@ export async function awsApiRequestREST(this: IHookFunctions | IExecuteFunctions
|
||||||
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
const response = await awsApiRequest.call(this, service, method, path, body, headers);
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response);
|
return JSON.parse(response);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +76,7 @@ export async function awsApiRequestSOAP(this: IHookFunctions | IExecuteFunctions
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -270,8 +272,8 @@ export class AwsSqs implements INodeType {
|
||||||
try {
|
try {
|
||||||
// loads first 1000 queues from SQS
|
// loads first 1000 queues from SQS
|
||||||
data = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `?Action=ListQueues`);
|
data = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `?Action=ListQueues`);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(`AWS Error: ${err}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let queues = data.ListQueuesResponse.ListQueuesResult.QueueUrl;
|
let queues = data.ListQueuesResponse.ListQueuesResult.QueueUrl;
|
||||||
|
@ -349,11 +351,11 @@ export class AwsSqs implements INodeType {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('No binary data set. So message attribute cannot be added!');
|
throw new NodeOperationError(this.getNode(), 'No binary data set. So message attribute cannot be added!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.binary[dataPropertyName] === undefined) {
|
if (item.binary[dataPropertyName] === undefined) {
|
||||||
throw new Error(`The binary property "${dataPropertyName}" does not exist. So message attribute cannot be added!`);
|
throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So message attribute cannot be added!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = item.binary[dataPropertyName].data;
|
const binaryData = item.binary[dataPropertyName].data;
|
||||||
|
@ -374,8 +376,8 @@ export class AwsSqs implements INodeType {
|
||||||
let responseData;
|
let responseData;
|
||||||
try {
|
try {
|
||||||
responseData = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `${queuePath}/?Action=${operation}&` + params.join('&'));
|
responseData = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `${queuePath}/?Action=${operation}&` + params.join('&'));
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(`AWS Error: ${err}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = responseData.SendMessageResponse.SendMessageResult;
|
const result = responseData.SendMessageResponse.SendMessageResult;
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -22,7 +24,7 @@ export async function bannerbearApiRequest(this: IExecuteFunctions | IWebhookFun
|
||||||
const credentials = this.getCredentials('bannerbearApi');
|
const credentials = this.getCredentials('bannerbearApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
const options: OptionsWithUri = {
|
||||||
|
@ -46,12 +48,7 @@ export async function bannerbearApiRequest(this: IExecuteFunctions | IWebhookFun
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response && error.response.body && error.response.body.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Try to return the error prettier
|
|
||||||
//@ts-ignore
|
|
||||||
throw new Error(`Bannerbear error response [${error.statusCode}]: ${error.response.body.message}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -18,7 +19,7 @@ export async function createDatapoint(this: IExecuteFunctions | IWebhookFunction
|
||||||
const credentials = this.getCredentials('beeminderApi');
|
const credentials = this.getCredentials('beeminderApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints.json`;
|
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints.json`;
|
||||||
|
@ -30,7 +31,7 @@ export async function getAllDatapoints(this: IExecuteFunctions | IHookFunctions
|
||||||
const credentials = this.getCredentials('beeminderApi');
|
const credentials = this.getCredentials('beeminderApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints.json`;
|
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints.json`;
|
||||||
|
@ -46,7 +47,7 @@ export async function updateDatapoint(this: IExecuteFunctions | IWebhookFunction
|
||||||
const credentials = this.getCredentials('beeminderApi');
|
const credentials = this.getCredentials('beeminderApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints/${data.datapointId}.json`;
|
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints/${data.datapointId}.json`;
|
||||||
|
@ -58,7 +59,7 @@ export async function deleteDatapoint(this: IExecuteFunctions | IWebhookFunction
|
||||||
const credentials = this.getCredentials('beeminderApi');
|
const credentials = this.getCredentials('beeminderApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints/${data.datapointId}.json`;
|
const endpoint = `/users/${credentials.user}/goals/${data.goalName}/datapoints/${data.datapointId}.json`;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -308,7 +309,7 @@ export class Beeminder implements INodeType {
|
||||||
const credentials = this.getCredentials('beeminderApi');
|
const credentials = this.getCredentials('beeminderApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/users/${credentials.user}/goals.json`;
|
const endpoint = `/users/${credentials.user}/goals.json`;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions,
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
const BEEMINDER_URI = 'https://www.beeminder.com/api/v1';
|
const BEEMINDER_URI = 'https://www.beeminder.com/api/v1';
|
||||||
|
@ -40,10 +41,7 @@ export async function beeminderApiRequest(this: IExecuteFunctions | IWebhookFunc
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
throw new Error(`Beeminder error response [${error.statusCode}]: ${error.message}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ export class BitbucketTrigger implements INodeType {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await bitbucketApiRequest.call(this, 'GET', endpoint);
|
await bitbucketApiRequest.call(this, 'GET', endpoint);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,12 +5,12 @@ import {
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function bitbucketApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function bitbucketApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('bitbucketApi');
|
const credentials = this.getCredentials('bitbucketApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
method,
|
method,
|
||||||
|
@ -30,8 +30,8 @@ export async function bitbucketApiRequest(this: IHookFunctions | IExecuteFunctio
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error('Bitbucket Error: ' + err.message);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function bitlyApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function bitlyApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -32,7 +32,7 @@ export async function bitlyApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
if (authenticationMethod === 'accessToken') {
|
if (authenticationMethod === 'accessToken') {
|
||||||
const credentials = this.getCredentials('bitlyApi');
|
const credentials = this.getCredentials('bitlyApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
options.headers = { Authorization: `Bearer ${credentials.accessToken}`};
|
options.headers = { Authorization: `Bearer ${credentials.accessToken}`};
|
||||||
|
|
||||||
|
@ -42,15 +42,7 @@ export async function bitlyApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
return await this.helpers.requestOAuth2!.call(this, 'bitlyOAuth2Api', options, { tokenType: 'Bearer' });
|
return await this.helpers.requestOAuth2!.call(this, 'bitlyOAuth2Api', options, { tokenType: 'Bearer' });
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response && error.response.body && error.response.body.message) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
const errorBody = error.response.body;
|
|
||||||
throw new Error(`Bitly error response [${error.statusCode}]: ${errorBody.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected error data did not get returned so throw the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -177,7 +178,7 @@ export class Bitwarden implements INodeType {
|
||||||
const updateFields = this.getNodeParameter('updateFields', i) as CollectionUpdateFields;
|
const updateFields = this.getNodeParameter('updateFields', i) as CollectionUpdateFields;
|
||||||
|
|
||||||
if (isEmpty(updateFields)) {
|
if (isEmpty(updateFields)) {
|
||||||
throw new Error(`Please enter at least one field to update for the ${resource}.`);
|
throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { groups, externalId } = updateFields;
|
const { groups, externalId } = updateFields;
|
||||||
|
@ -308,7 +309,7 @@ export class Bitwarden implements INodeType {
|
||||||
const updateFields = this.getNodeParameter('updateFields', i) as GroupUpdateFields;
|
const updateFields = this.getNodeParameter('updateFields', i) as GroupUpdateFields;
|
||||||
|
|
||||||
if (isEmpty(updateFields)) {
|
if (isEmpty(updateFields)) {
|
||||||
throw new Error(`Please enter at least one field to update for the ${resource}.`);
|
throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set defaults for `name` and `accessAll`, required by Bitwarden but optional in n8n
|
// set defaults for `name` and `accessAll`, required by Bitwarden but optional in n8n
|
||||||
|
@ -452,7 +453,7 @@ export class Bitwarden implements INodeType {
|
||||||
const updateFields = this.getNodeParameter('updateFields', i) as MemberUpdateFields;
|
const updateFields = this.getNodeParameter('updateFields', i) as MemberUpdateFields;
|
||||||
|
|
||||||
if (isEmpty(updateFields)) {
|
if (isEmpty(updateFields)) {
|
||||||
throw new Error(`Please enter at least one field to update for the ${resource}.`);
|
throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { accessAll, collections, externalId, type } = updateFields;
|
const { accessAll, collections, externalId, type } = updateFields;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -48,17 +49,7 @@ export async function bitwardenApiRequest(
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.statusCode === 404) {
|
|
||||||
throw new Error('Bitwarden error response [404]: Not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error?.response?.body?.Message) {
|
|
||||||
const message = error?.response?.body?.Message;
|
|
||||||
throw new Error(`Bitwarden error response [${error.statusCode}]: ${message}`);
|
|
||||||
}
|
|
||||||
//TODO handle Errors array
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +84,7 @@ export async function getAccessToken(
|
||||||
const { access_token } = await this.helpers.request!(options);
|
const { access_token } = await this.helpers.request!(options);
|
||||||
return access_token;
|
return access_token;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -217,11 +218,11 @@ export class Box implements INodeType {
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string;
|
||||||
|
|
||||||
if (items[i].binary === undefined) {
|
if (items[i].binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (items[i].binary[binaryPropertyName] === undefined) {
|
if (items[i].binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
||||||
|
@ -248,7 +249,7 @@ export class Box implements INodeType {
|
||||||
const content = this.getNodeParameter('fileContent', i) as string;
|
const content = this.getNodeParameter('fileContent', i) as string;
|
||||||
|
|
||||||
if (fileName === '') {
|
if (fileName === '') {
|
||||||
throw new Error('File name must be set!');
|
throw new NodeOperationError(this.getNode(), 'File name must be set!');
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes['name'] = fileName;
|
attributes['name'] = fileName;
|
||||||
|
|
|
@ -327,7 +327,7 @@ export class BoxTrigger implements INodeType {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await boxApiRequest.call(this, 'DELETE', endpoint);
|
await boxApiRequest.call(this, 'DELETE', endpoint);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IOAuth2Options,
|
IOAuth2Options,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function boxApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IHookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function boxApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IHookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -41,22 +42,7 @@ export async function boxApiRequest(this: IExecuteFunctions | IExecuteSingleFunc
|
||||||
return await this.helpers.requestOAuth2.call(this, 'boxOAuth2Api', options, oAuth2Options);
|
return await this.helpers.requestOAuth2.call(this, 'boxOAuth2Api', options, oAuth2Options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
let errorMessage;
|
|
||||||
|
|
||||||
if (error.response && error.response.body) {
|
|
||||||
|
|
||||||
if (error.response.body.context_info && error.response.body.context_info.errors) {
|
|
||||||
const errors = error.response.body.context_info.errors;
|
|
||||||
errorMessage = errors.map((e: IDataObject) => e.message);
|
|
||||||
errorMessage = errorMessage.join('|');
|
|
||||||
} else if (error.response.body.message) {
|
|
||||||
errorMessage = error.response.body.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Box error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function brandfetchApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function brandfetchApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
try {
|
try {
|
||||||
const credentials = this.getCredentials('brandfetchApi');
|
const credentials = this.getCredentials('brandfetchApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -46,20 +46,12 @@ export async function brandfetchApiRequest(this: IHookFunctions | IExecuteFuncti
|
||||||
const response = await this.helpers.request!(options);
|
const response = await this.helpers.request!(options);
|
||||||
|
|
||||||
if (response.statusCode && response.statusCode !== 200) {
|
if (response.statusCode && response.statusCode !== 200) {
|
||||||
throw new Error(`Brandfetch error response [${response.statusCode}]: ${response.response}`);
|
throw new NodeApiError(this.getNode(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response && error.response.body && error.response.body.message) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
const errorBody = error.response.body;
|
|
||||||
throw new Error(`Brandfetch error response [${error.statusCode}]: ${errorBody.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected error data did not get returned so throw the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -153,7 +154,7 @@ export class Bubble implements INodeType {
|
||||||
const filter = options.filtersJson as string;
|
const filter = options.filtersJson as string;
|
||||||
const data = validateJSON(filter);
|
const data = validateJSON(filter);
|
||||||
if (data === undefined) {
|
if (data === undefined) {
|
||||||
throw new Error('Filters must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Filters must be a valid JSON');
|
||||||
}
|
}
|
||||||
qs.constraints = JSON.stringify(data);
|
qs.constraints = JSON.stringify(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -57,11 +58,7 @@ export async function bubbleApiRequest(
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.response?.body?.body?.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
const errorMessage = error.response.body.body.message;
|
|
||||||
throw new Error(`Bubble.io error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ export class CalendlyTrigger implements INodeType {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await calendlyApiRequest.call(this, 'DELETE', endpoint);
|
await calendlyApiRequest.call(this, 'DELETE', endpoint);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function calendlyApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function calendlyApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -16,7 +18,7 @@ export async function calendlyApiRequest(this: IExecuteFunctions | IWebhookFunct
|
||||||
const credentials = this.getCredentials('calendlyApi');
|
const credentials = this.getCredentials('calendlyApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = 'https://calendly.com/api/v1';
|
const endpoint = 'https://calendly.com/api/v1';
|
||||||
|
@ -42,10 +44,6 @@ export async function calendlyApiRequest(this: IExecuteFunctions | IWebhookFunct
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
const errorMessage = error.response.body.message || error.response.body.description || error.message;
|
|
||||||
throw new Error(`Calendly error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
NodeParameterValue,
|
NodeParameterValue,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
@ -489,7 +491,7 @@ export class Chargebee implements INodeType {
|
||||||
const credentials = this.getCredentials('chargebeeApi');
|
const credentials = this.getCredentials('chargebeeApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseUrl = `https://${credentials.accountName}.chargebee.com/api/v2`;
|
const baseUrl = `https://${credentials.accountName}.chargebee.com/api/v2`;
|
||||||
|
@ -531,7 +533,7 @@ export class Chargebee implements INodeType {
|
||||||
|
|
||||||
endpoint = `customers`;
|
endpoint = `customers`;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (resource === 'invoice') {
|
} else if (resource === 'invoice') {
|
||||||
|
@ -569,7 +571,7 @@ export class Chargebee implements INodeType {
|
||||||
const invoiceId = this.getNodeParameter('invoiceId', i) as string;
|
const invoiceId = this.getNodeParameter('invoiceId', i) as string;
|
||||||
endpoint = `invoices/${invoiceId.trim()}/pdf`;
|
endpoint = `invoices/${invoiceId.trim()}/pdf`;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (resource === 'subscription') {
|
} else if (resource === 'subscription') {
|
||||||
|
@ -595,10 +597,10 @@ export class Chargebee implements INodeType {
|
||||||
|
|
||||||
endpoint = `subscriptions/${subscriptionId.trim()}/delete`;
|
endpoint = `subscriptions/${subscriptionId.trim()}/delete`;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The resource "${resource}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -613,7 +615,13 @@ export class Chargebee implements INodeType {
|
||||||
json: true,
|
json: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const responseData = await this.helpers.request!(options);
|
let responseData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
responseData = await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
|
||||||
if (resource === 'invoice' && operation === 'list') {
|
if (resource === 'invoice' && operation === 'list') {
|
||||||
responseData.list.forEach((data: IDataObject) => {
|
responseData.list.forEach((data: IDataObject) => {
|
||||||
|
|
|
@ -10,13 +10,13 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function circleciApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function circleciApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('circleCiApi');
|
const credentials = this.getCredentials('circleCiApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -35,14 +35,9 @@ export async function circleciApiRequest(this: IHookFunctions | IExecuteFunction
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
if (err.response && err.response.body && err.response.body.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Try to return the error prettier
|
}
|
||||||
throw new Error(`CircleCI error response [${err.statusCode}]: ${err.response.body.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw err; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,14 +9,12 @@ import {
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
IDataObject,
|
|
||||||
} from 'n8n-workflow';
|
|
||||||
|
|
||||||
export async function clearbitApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, api: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function clearbitApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, api: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('clearbitApi');
|
const credentials = this.getCredentials('clearbitApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
headers: { Authorization: `Bearer ${credentials.apiKey}` },
|
headers: { Authorization: `Bearer ${credentials.apiKey}` },
|
||||||
|
@ -33,17 +31,6 @@ export async function clearbitApiRequest(this: IHookFunctions | IExecuteFunction
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Clearbit credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.response.body && error.response.body.error && error.response.body.error.message) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
throw new Error(`Clearbit Error [${error.statusCode}]: ${error.response.body.error.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw new Error('Clearbit Error: ' + error.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -719,14 +720,14 @@ export class ClickUp implements INodeType {
|
||||||
};
|
};
|
||||||
if (type === 'number' || type === 'currency') {
|
if (type === 'number' || type === 'currency') {
|
||||||
if (!additionalFields.unit) {
|
if (!additionalFields.unit) {
|
||||||
throw new Error('Unit field must be set');
|
throw new NodeOperationError(this.getNode(), 'Unit field must be set');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type === 'number' || type === 'percentaje'
|
if (type === 'number' || type === 'percentaje'
|
||||||
|| type === 'automatic' || type === 'currency') {
|
|| type === 'automatic' || type === 'currency') {
|
||||||
if (additionalFields.stepsStart === undefined
|
if (additionalFields.stepsStart === undefined
|
||||||
|| !additionalFields.stepsEnd === undefined) {
|
|| !additionalFields.stepsEnd === undefined) {
|
||||||
throw new Error('Steps start and steps end fields must be set');
|
throw new NodeOperationError(this.getNode(), 'Steps start and steps end fields must be set');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (additionalFields.unit) {
|
if (additionalFields.unit) {
|
||||||
|
@ -845,7 +846,7 @@ export class ClickUp implements INodeType {
|
||||||
if (additionalFields.customFieldsJson) {
|
if (additionalFields.customFieldsJson) {
|
||||||
const customFields = validateJSON(additionalFields.customFieldsJson as string);
|
const customFields = validateJSON(additionalFields.customFieldsJson as string);
|
||||||
if (customFields === undefined) {
|
if (customFields === undefined) {
|
||||||
throw new Error('Custom Fields: Invalid JSON');
|
throw new NodeOperationError(this.getNode(), 'Custom Fields: Invalid JSON');
|
||||||
}
|
}
|
||||||
body.custom_fields = customFields;
|
body.custom_fields = customFields;
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1043,7 @@ export class ClickUp implements INodeType {
|
||||||
if (jsonParse === true) {
|
if (jsonParse === true) {
|
||||||
body.value = validateJSON(body.value);
|
body.value = validateJSON(body.value);
|
||||||
if (body.value === undefined) {
|
if (body.value === undefined) {
|
||||||
throw new Error('Value is invalid JSON!');
|
throw new NodeOperationError(this.getNode(), 'Value is invalid JSON!');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
@ -1213,7 +1214,7 @@ export class ClickUp implements INodeType {
|
||||||
if (responseData.data) {
|
if (responseData.data) {
|
||||||
responseData = responseData.data;
|
responseData = responseData.data;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('There seems to be nothing to stop.');
|
throw new NodeOperationError(this.getNode(), 'There seems to be nothing to stop.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (operation === 'delete') {
|
if (operation === 'delete') {
|
||||||
|
@ -1233,7 +1234,7 @@ export class ClickUp implements INodeType {
|
||||||
if (tagsUi) {
|
if (tagsUi) {
|
||||||
const tags = (tagsUi as IDataObject).tagsValues as IDataObject[];
|
const tags = (tagsUi as IDataObject).tagsValues as IDataObject[];
|
||||||
if (tags === undefined) {
|
if (tags === undefined) {
|
||||||
throw new Error('At least one tag must be set');
|
throw new NodeOperationError(this.getNode(), 'At least one tag must be set');
|
||||||
}
|
}
|
||||||
body.tags = tags;
|
body.tags = tags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,10 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IOAuth2Options,
|
IOAuth2Options,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const options: OptionsWithUri = {
|
const options: OptionsWithUri = {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -34,15 +36,10 @@ export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions
|
||||||
|
|
||||||
const credentials = this.getCredentials('clickUpApi');
|
const credentials = this.getCredentials('clickUpApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
options.headers!['Authorization'] = credentials?.accessToken;
|
||||||
throw new Error('No credentials got returned!');
|
|
||||||
}
|
|
||||||
|
|
||||||
options.headers!['Authorization'] = credentials.accessToken;
|
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const oAuth2Options: IOAuth2Options = {
|
const oAuth2Options: IOAuth2Options = {
|
||||||
keepBearer: false,
|
keepBearer: false,
|
||||||
tokenType: 'Bearer',
|
tokenType: 'Bearer',
|
||||||
|
@ -50,15 +47,9 @@ export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return await this.helpers.requestOAuth2!.call(this, 'clickUpOAuth2Api', options, oAuth2Options);
|
return await this.helpers.requestOAuth2!.call(this, 'clickUpOAuth2Api', options, oAuth2Options);
|
||||||
}
|
}
|
||||||
|
} catch(error) {
|
||||||
} catch (error) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
let errorMessage = error;
|
|
||||||
if (error.err) {
|
|
||||||
errorMessage = error.err;
|
|
||||||
}
|
|
||||||
throw new Error('ClickUp Error: ' + errorMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clickupApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function clickupApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function clockifyApiRequest(this: ILoadOptionsFunctions | IPollFunctions | IExecuteFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function clockifyApiRequest(this: ILoadOptionsFunctions | IPollFunctions | IExecuteFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -17,7 +17,7 @@ export async function clockifyApiRequest(this: ILoadOptionsFunctions | IPollFunc
|
||||||
const credentials = this.getCredentials('clockifyApi');
|
const credentials = this.getCredentials('clockifyApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
|
|
||||||
}
|
}
|
||||||
const BASE_URL = 'https://api.clockify.me/api/v1';
|
const BASE_URL = 'https://api.clockify.me/api/v1';
|
||||||
|
@ -36,20 +36,9 @@ export async function clockifyApiRequest(this: ILoadOptionsFunctions | IPollFunc
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
let errorMessage = error.message;
|
|
||||||
|
|
||||||
if (error.response.body && error.response.body.message) {
|
|
||||||
|
|
||||||
errorMessage = `[${error.statusCode}] ${error.response.body.message}`;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('Clockify Error: ' + errorMessage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ import {
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
import { OptionsWithUri } from 'request';
|
import { OptionsWithUri } from 'request';
|
||||||
|
|
||||||
export async function cockpitApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function cockpitApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('cockpitApi');
|
const credentials = this.getCredentials('cockpitApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials available.');
|
throw new NodeOperationError(this.getNode(), 'No credentials available.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
|
@ -36,12 +36,7 @@ export async function cockpitApiRequest(this: IExecuteFunctions | IExecuteSingle
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let errorMessage = error.message;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.error) {
|
|
||||||
errorMessage = error.error.message || error.error.error;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Cockpit error [${error.statusCode}]: ` + errorMessage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import {
|
import {
|
||||||
codaApiRequest,
|
codaApiRequest,
|
||||||
|
@ -338,8 +340,8 @@ export class Coda implements INodeType {
|
||||||
responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs);
|
responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||||
responseData = responseData.items;
|
responseData = responseData.items;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(`Coda Error: ${err.message}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rawData === true) {
|
if (options.rawData === true) {
|
||||||
|
@ -540,8 +542,8 @@ export class Coda implements INodeType {
|
||||||
responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs);
|
responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||||
responseData = responseData.items;
|
responseData = responseData.items;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(`Coda Error: ${err.message}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rawData === true) {
|
if (options.rawData === true) {
|
||||||
|
|
|
@ -4,12 +4,12 @@ import {
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function codaApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function codaApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const credentials = this.getCredentials('codaApi');
|
const credentials = this.getCredentials('codaApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
|
@ -28,12 +28,7 @@ export async function codaApiRequest(this: IExecuteFunctions | IExecuteSingleFun
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let errorMessage = error.message;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response.body) {
|
|
||||||
errorMessage = error.response.body.message || error.response.body.Message || error.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('Coda Error: ' + errorMessage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function coinGeckoApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string,
|
export async function coinGeckoApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string,
|
||||||
|
@ -37,8 +37,7 @@ export async function coinGeckoApiRequest(this: IExecuteFunctions | IExecuteSing
|
||||||
return await this.helpers.request.call(this, options);
|
return await this.helpers.request.call(this, options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import * as fflate from 'fflate';
|
import * as fflate from 'fflate';
|
||||||
|
@ -216,11 +217,11 @@ export class Compression implements INodeType {
|
||||||
|
|
||||||
for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) {
|
for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) {
|
||||||
if (items[i].binary === undefined) {
|
if (items[i].binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (items[i].binary[binaryPropertyName] === undefined) {
|
if (items[i].binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
||||||
|
@ -270,11 +271,11 @@ export class Compression implements INodeType {
|
||||||
for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) {
|
for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) {
|
||||||
|
|
||||||
if (items[i].binary === undefined) {
|
if (items[i].binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (items[i].binary[binaryPropertyName] === undefined) {
|
if (items[i].binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
|
||||||
|
|
|
@ -9,14 +9,14 @@ import {
|
||||||
} from 'request';
|
} from 'request';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function contentfulApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function contentfulApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
|
||||||
const credentials = this.getCredentials('contentfulApi');
|
const credentials = this.getCredentials('contentfulApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const source = this.getNodeParameter('source', 0) as string;
|
const source = this.getNodeParameter('source', 0) as string;
|
||||||
|
@ -39,7 +39,7 @@ export async function contentfulApiRequest(this: IExecuteFunctions | IExecuteSin
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Contentful error response [${error.statusCode}]: ${error.error.message}`);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions
|
IHookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function convertKitApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IHookFunctions,
|
export async function convertKitApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IHookFunctions,
|
||||||
|
@ -19,7 +21,7 @@ export async function convertKitApiRequest(this: IExecuteFunctions | IExecuteSin
|
||||||
const credentials = this.getCredentials('convertKitApi');
|
const credentials = this.getCredentials('convertKitApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
|
@ -51,17 +53,8 @@ export async function convertKitApiRequest(this: IExecuteFunctions | IExecuteSin
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
let errorMessage = error;
|
|
||||||
|
|
||||||
if (error.response && error.response.body && error.response.body.message) {
|
|
||||||
errorMessage = error.response.body.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`ConvertKit error response: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ export class CopperTrigger implements INodeType {
|
||||||
const endpoint = `/webhooks/${webhookData.webhookId}`;
|
const endpoint = `/webhooks/${webhookData.webhookId}`;
|
||||||
try {
|
try {
|
||||||
await copperApiRequest.call(this, 'GET', endpoint);
|
await copperApiRequest.call(this, 'GET', endpoint);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -72,12 +73,7 @@ export async function copperApiRequest(
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let errorMessage = error.message;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response.body?.message) {
|
|
||||||
errorMessage = error.response.body.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Copper error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -231,13 +232,13 @@ export class Cortex implements INodeType {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string;
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string;
|
||||||
|
|
||||||
if (item.binary[binaryPropertyName] === undefined) {
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
||||||
|
@ -386,13 +387,13 @@ export class Cortex implements INodeType {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryPropertyName = artifactvalue.binaryProperty as string;
|
const binaryPropertyName = artifactvalue.binaryProperty as string;
|
||||||
|
|
||||||
if (item.binary[binaryPropertyName] === undefined) {
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property '${binaryPropertyName}' does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryData = item.binary[binaryPropertyName] as IBinaryData;
|
const binaryData = item.binary[binaryPropertyName] as IBinaryData;
|
||||||
|
@ -415,12 +416,12 @@ export class Cortex implements INodeType {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryPropertyName = (body.data as IDataObject).binaryPropertyName as string;
|
const binaryPropertyName = (body.data as IDataObject).binaryPropertyName as string;
|
||||||
if (item.binary[binaryPropertyName] === undefined) {
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
@ -26,7 +26,7 @@ export async function cortexApiRequest(this: IHookFunctions | IExecuteFunctions
|
||||||
const credentials = this.getCredentials('cortexApi');
|
const credentials = this.getCredentials('cortexApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerWithAuthentication = Object.assign({}, { Authorization: ` Bearer ${credentials.cortexApiKey}` });
|
const headerWithAuthentication = Object.assign({}, { Authorization: ` Bearer ${credentials.cortexApiKey}` });
|
||||||
|
@ -53,10 +53,7 @@ export async function cortexApiRequest(this: IHookFunctions | IExecuteFunctions
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.error) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
const errorMessage = `Cortex error response [${error.statusCode}]: ${error.error.message}`;
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
} else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -188,7 +189,7 @@ export class CrateDb implements INodeType {
|
||||||
const credentials = this.getCredentials('crateDb');
|
const credentials = this.getCredentials('crateDb');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const pgp = pgPromise();
|
const pgp = pgPromise();
|
||||||
|
@ -262,7 +263,7 @@ export class CrateDb implements INodeType {
|
||||||
updateKeyValue = item.json[updateKey] as string | number;
|
updateKeyValue = item.json[updateKey] as string | number;
|
||||||
|
|
||||||
if (updateKeyValue === undefined) {
|
if (updateKeyValue === undefined) {
|
||||||
throw new Error('No value found for update key!');
|
throw new NodeOperationError(this.getNode(), 'No value found for update key!');
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedKeys.push(updateKeyValue as string);
|
updatedKeys.push(updateKeyValue as string);
|
||||||
|
@ -277,7 +278,7 @@ export class CrateDb implements INodeType {
|
||||||
returnItems = this.helpers.returnJsonArray(getItemCopy(items, columns) as IDataObject[]);
|
returnItems = this.helpers.returnJsonArray(getItemCopy(items, columns) as IDataObject[]);
|
||||||
} else {
|
} else {
|
||||||
await pgp.end();
|
await pgp.end();
|
||||||
throw new Error(`The operation "${operation}" is not supported!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the connection
|
// Close the connection
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import {
|
import {
|
||||||
customerIoApiRequest,
|
customerIoApiRequest,
|
||||||
|
@ -131,7 +132,7 @@ export class CustomerIo implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -175,7 +176,7 @@ export class CustomerIo implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,7 +239,7 @@ export class CustomerIo implements INodeType {
|
||||||
if (validateJSON(additionalFieldsJson) !== undefined) {
|
if (validateJSON(additionalFieldsJson) !== undefined) {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -283,7 +284,7 @@ export class CustomerIo implements INodeType {
|
||||||
Object.assign(body, JSON.parse(additionalFieldsJson));
|
Object.assign(body, JSON.parse(additionalFieldsJson));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Additional fields must be a valid JSON');
|
throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -308,7 +308,7 @@ export class CustomerIoTrigger implements INodeType {
|
||||||
const endpoint = `/reporting_webhooks/${webhookData.webhookId}`;
|
const endpoint = `/reporting_webhooks/${webhookData.webhookId}`;
|
||||||
try {
|
try {
|
||||||
await customerIoApiRequest.call(this, 'DELETE', endpoint, {}, 'beta');
|
await customerIoApiRequest.call(this, 'DELETE', endpoint, {}, 'beta');
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
delete webhookData.webhookId;
|
delete webhookData.webhookId;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'request';
|
} from 'request';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -20,7 +20,7 @@ export async function customerIoApiRequest(this: IHookFunctions | IExecuteFuncti
|
||||||
const credentials = this.getCredentials('customerIoApi');
|
const credentials = this.getCredentials('customerIoApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
query = query || {};
|
query = query || {};
|
||||||
|
@ -51,19 +51,7 @@ export async function customerIoApiRequest(this: IHookFunctions | IExecuteFuncti
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Customer.io credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.response && error.response.body && error.response.body.error_code) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
const errorBody = error.response.body;
|
|
||||||
throw new Error(`Customer.io error response [${errorBody.error_code}]: ${errorBody.description}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected error data did not get returned so throw the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ export class DateTime implements INodeType {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (options.fromFormat === undefined && !moment(currentDate as string | number).isValid()) {
|
if (options.fromFormat === undefined && !moment(currentDate as string | number).isValid()) {
|
||||||
throw new Error('The date input format could not be recognized. Please set the "From Format" field');
|
throw new NodeOperationError(this.getNode(), 'The date input format could not be recognized. Please set the "From Format" field');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Number.isInteger(currentDate as unknown as number)) {
|
if (Number.isInteger(currentDate as unknown as number)) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function deepLApiRequest(
|
export async function deepLApiRequest(
|
||||||
|
@ -45,7 +45,7 @@ export async function deepLApiRequest(
|
||||||
const credentials = this.getCredentials('deepLApi');
|
const credentials = this.getCredentials('deepLApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.qs.auth_key = credentials.apiKey;
|
options.qs.auth_key = credentials.apiKey;
|
||||||
|
@ -53,10 +53,6 @@ export async function deepLApiRequest(
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.response?.body?.message) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Try to return the error prettier
|
|
||||||
throw new Error(`DeepL error response [${error.statusCode}]: ${error.response.body.message}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,14 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError, NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function demioApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function demioApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
try {
|
try {
|
||||||
const credentials = this.getCredentials('demioApi');
|
const credentials = this.getCredentials('demioApi');
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -35,14 +35,6 @@ export async function demioApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
|
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response && error.response.body && error.response.body.message) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
const errorBody = error.response.body;
|
|
||||||
throw new Error(`Demio error response [${error.statusCode}]: ${errorBody.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected error data did not get returned so throw the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export class Discord implements INodeType {
|
export class Discord implements INodeType {
|
||||||
|
@ -86,15 +88,14 @@ export class Discord implements INodeType {
|
||||||
}, get(error, 'response.body.retry_after', 150));
|
}, get(error, 'response.body.retry_after', 150));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// If it's another error code then return the JSON response
|
throw new NodeApiError(this.getNode(), error);
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (--maxTries);
|
} while (--maxTries);
|
||||||
|
|
||||||
if (maxTries <= 0) {
|
if (maxTries <= 0) {
|
||||||
throw new Error('Could not send message. Max. amount of rate-limit retries got reached.');
|
throw new NodeApiError(this.getNode(), { request: options }, { message: 'Could not send message. Max. amount of rate-limit retries got reached.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
returnData.push({success: true});
|
returnData.push({success: true});
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function discourseApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, path: string, body: any = {}, qs: IDataObject = {}, option = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function discourseApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, path: string, body: any = {}, qs: IDataObject = {}, option = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -35,15 +35,7 @@ export async function discourseApiRequest(this: IExecuteFunctions | IExecuteSing
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
return await this.helpers.request.call(this, options);
|
return await this.helpers.request.call(this, options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response && error.response.body && error.response.body.errors) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
|
||||||
const errors = error.response.body.errors;
|
|
||||||
// Try to return the error prettier
|
|
||||||
throw new Error(
|
|
||||||
`Discourse error response [${error.statusCode}]: ${errors.join('|')}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { disqusApiRequest, disqusApiRequestAllItems } from './GenericFunctions';
|
import { disqusApiRequest, disqusApiRequestAllItems } from './GenericFunctions';
|
||||||
|
@ -771,11 +772,11 @@ export class Disqus implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The resource "${resource}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject, NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function disqusApiRequest(
|
export async function disqusApiRequest(
|
||||||
this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
|
@ -19,7 +19,7 @@ export async function disqusApiRequest(
|
||||||
const credentials = this.getCredentials('disqusApi') as IDataObject;
|
const credentials = this.getCredentials('disqusApi') as IDataObject;
|
||||||
qs.api_key = credentials.accessToken;
|
qs.api_key = credentials.accessToken;
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to query string into a format the API can read
|
// Convert to query string into a format the API can read
|
||||||
|
@ -46,21 +46,9 @@ export async function disqusApiRequest(
|
||||||
delete options.body;
|
delete options.body;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result = await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
return result;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Disqus credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.error && error.error.error_summary) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
throw new Error(`Disqus error response [${error.statusCode}]: ${error.error.error_summary}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function driftApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function driftApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
@ -36,7 +38,7 @@ export async function driftApiRequest(this: IExecuteFunctions | IWebhookFunction
|
||||||
const credentials = this.getCredentials('driftApi');
|
const credentials = this.getCredentials('driftApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.headers!['Authorization'] = `Bearer ${credentials.accessToken}`;
|
options.headers!['Authorization'] = `Bearer ${credentials.accessToken}`;
|
||||||
|
@ -46,11 +48,6 @@ export async function driftApiRequest(this: IExecuteFunctions | IWebhookFunction
|
||||||
return await this.helpers.requestOAuth2!.call(this, 'driftOAuth2Api', options);
|
return await this.helpers.requestOAuth2!.call(this, 'driftOAuth2Api', options);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error.response && error.response.body && error.response.body.error) {
|
|
||||||
const errorMessage = error.response.body.error.message;
|
|
||||||
throw new Error(`Drift error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -849,13 +850,13 @@ export class Dropbox implements INodeType {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('No binary data exists on item!');
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on item!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string;
|
const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string;
|
||||||
|
|
||||||
if (item.binary[propertyNameUpload] === undefined) {
|
if (item.binary[propertyNameUpload] === undefined) {
|
||||||
throw new Error(`No binary data property "${propertyNameUpload}" does not exists on item!`);
|
throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING);
|
body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING);
|
||||||
|
@ -980,7 +981,7 @@ export class Dropbox implements INodeType {
|
||||||
endpoint = 'https://api.dropboxapi.com/2/files/move_v2';
|
endpoint = 'https://api.dropboxapi.com/2/files/move_v2';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`The resource "${resource}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource === 'file' && operation === 'download') {
|
if (resource === 'file' && operation === 'download') {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from 'request';
|
} from 'request';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,20 +51,7 @@ export async function dropboxApiRequest(this: IHookFunctions | IExecuteFunctions
|
||||||
return await this.helpers.requestOAuth2.call(this, 'dropboxOAuth2Api', options);
|
return await this.helpers.requestOAuth2.call(this, 'dropboxOAuth2Api', options);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.statusCode === 401) {
|
throw new NodeApiError(this.getNode(), error);
|
||||||
// Return a clear error
|
|
||||||
throw new Error('The Dropbox credentials are not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.error && error.error.error_summary) {
|
|
||||||
// Try to return the error prettier
|
|
||||||
throw new Error(
|
|
||||||
`Dropbox error response [${error.statusCode}]: ${error.error.error_summary}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that data does not exist for some reason return the actual error
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -206,7 +207,7 @@ export class ERPNext implements INodeType {
|
||||||
const properties = this.getNodeParameter('properties', i) as DocumentProperties;
|
const properties = this.getNodeParameter('properties', i) as DocumentProperties;
|
||||||
|
|
||||||
if (!properties.customProperty.length) {
|
if (!properties.customProperty.length) {
|
||||||
throw new Error('Please enter at least one property for the document to create.');
|
throw new NodeOperationError(this.getNode(), 'Please enter at least one property for the document to create.');
|
||||||
}
|
}
|
||||||
|
|
||||||
properties.customProperty.forEach(property => {
|
properties.customProperty.forEach(property => {
|
||||||
|
@ -242,7 +243,7 @@ export class ERPNext implements INodeType {
|
||||||
const properties = this.getNodeParameter('properties', i) as DocumentProperties;
|
const properties = this.getNodeParameter('properties', i) as DocumentProperties;
|
||||||
|
|
||||||
if (!properties.customProperty.length) {
|
if (!properties.customProperty.length) {
|
||||||
throw new Error('Please enter at least one property for the document to update.');
|
throw new NodeOperationError(this.getNode(), 'Please enter at least one property for the document to update.');
|
||||||
}
|
}
|
||||||
|
|
||||||
properties.customProperty.forEach(property => {
|
properties.customProperty.forEach(property => {
|
||||||
|
|
|
@ -10,7 +10,9 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
IWebhookFunctions
|
IWebhookFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function erpNextApiRequest(
|
export async function erpNextApiRequest(
|
||||||
|
@ -26,7 +28,7 @@ export async function erpNextApiRequest(
|
||||||
const credentials = this.getCredentials('erpNextApi');
|
const credentials = this.getCredentials('erpNextApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: OptionsWithUri = {
|
let options: OptionsWithUri = {
|
||||||
|
@ -56,27 +58,15 @@ export async function erpNextApiRequest(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
if (error.statusCode === 403) {
|
if (error.statusCode === 403) {
|
||||||
throw new Error(
|
throw new NodeApiError(this.getNode(), { message: `DocType unavailable.` });
|
||||||
`ERPNext error response [${error.statusCode}]: DocType unavailable.`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error.statusCode === 307) {
|
if (error.statusCode === 307) {
|
||||||
throw new Error(
|
throw new NodeApiError(this.getNode(), { message:`Please ensure the subdomain is correct.` });
|
||||||
`ERPNext error response [${error.statusCode}]: Please ensure the subdomain is correct.`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let errorMessages;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error?.response?.body?._server_messages) {
|
|
||||||
const errors = JSON.parse(error.response.body._server_messages);
|
|
||||||
errorMessages = errors.map((e: string) => JSON.parse(e).message);
|
|
||||||
throw new Error(
|
|
||||||
`ARPNext error response [${error.statusCode}]: ${errorMessages.join('|')}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import * as gm from 'gm';
|
import * as gm from 'gm';
|
||||||
import { file } from 'tmp-promise';
|
import { file } from 'tmp-promise';
|
||||||
|
@ -1041,7 +1042,7 @@ export class EditImage implements INodeType {
|
||||||
requiredOperationParameters[operation].forEach(parameterName => {
|
requiredOperationParameters[operation].forEach(parameterName => {
|
||||||
try {
|
try {
|
||||||
operationParameters[parameterName] = this.getNodeParameter(parameterName, itemIndex);
|
operationParameters[parameterName] = this.getNodeParameter(parameterName, itemIndex);
|
||||||
} catch (e) {}
|
} catch (error) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1055,11 +1056,11 @@ export class EditImage implements INodeType {
|
||||||
if (operations[0].operation !== 'create') {
|
if (operations[0].operation !== 'create') {
|
||||||
// "create" generates a new image so does not require any incoming data.
|
// "create" generates a new image so does not require any incoming data.
|
||||||
if (item.binary === undefined) {
|
if (item.binary === undefined) {
|
||||||
throw new Error('Item does not contain any binary data.');
|
throw new NodeOperationError(this.getNode(), 'Item does not contain any binary data.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.binary[dataPropertyName as string] === undefined) {
|
if (item.binary[dataPropertyName as string] === undefined) {
|
||||||
throw new Error(`Item does not contain any binary data with the name "${dataPropertyName}".`);
|
throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${dataPropertyName}".`);
|
||||||
}
|
}
|
||||||
|
|
||||||
gmInstance = gm(Buffer.from(item.binary![dataPropertyName as string].data, BINARY_ENCODING));
|
gmInstance = gm(Buffer.from(item.binary![dataPropertyName as string].data, BINARY_ENCODING));
|
||||||
|
@ -1095,7 +1096,7 @@ export class EditImage implements INodeType {
|
||||||
const geometryString = (positionX >= 0 ? '+' : '') + positionX + (positionY >= 0 ? '+' : '') + positionY;
|
const geometryString = (positionX >= 0 ? '+' : '') + positionX + (positionY >= 0 ? '+' : '') + positionY;
|
||||||
|
|
||||||
if (item.binary![operationData.dataPropertyNameComposite as string] === undefined) {
|
if (item.binary![operationData.dataPropertyNameComposite as string] === undefined) {
|
||||||
throw new Error(`Item does not contain any binary data with the name "${operationData.dataPropertyNameComposite}".`);
|
throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${operationData.dataPropertyNameComposite}".`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { fd, path, cleanup } = await file();
|
const { fd, path, cleanup } = await file();
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject, NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
interface IContact {
|
interface IContact {
|
||||||
|
@ -58,20 +58,7 @@ export async function egoiApiRequest(this: IHookFunctions | IExecuteFunctions |
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let errorMessage;
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
|
||||||
if (error.response && error.response.body) {
|
|
||||||
|
|
||||||
if (Array.isArray(error.response.body.errors)) {
|
|
||||||
const errors = error.response.body.errors;
|
|
||||||
errorMessage = errors.map((e: IDataObject) => e.detail);
|
|
||||||
} else {
|
|
||||||
errorMessage = error.response.body.detail;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`e-goi Error response [${error.statusCode}]: ${errorMessage}`);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
ITriggerResponse,
|
ITriggerResponse,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -168,7 +169,7 @@ export class EmailReadImap implements INodeType {
|
||||||
const credentials = this.getCredentials('imap');
|
const credentials = this.getCredentials('imap');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const mailbox = this.getNodeParameter('mailbox') as string;
|
const mailbox = this.getNodeParameter('mailbox') as string;
|
||||||
|
@ -181,8 +182,8 @@ export class EmailReadImap implements INodeType {
|
||||||
if (options.customEmailConfig !== undefined) {
|
if (options.customEmailConfig !== undefined) {
|
||||||
try {
|
try {
|
||||||
searchCriteria = JSON.parse(options.customEmailConfig as string);
|
searchCriteria = JSON.parse(options.customEmailConfig as string);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(`Custom email config is not valid JSON.`);
|
throw new NodeOperationError(this.getNode(), `Custom email config is not valid JSON.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +280,7 @@ export class EmailReadImap implements INodeType {
|
||||||
const part = lodash.find(message.parts, { which: '' });
|
const part = lodash.find(message.parts, { which: '' });
|
||||||
|
|
||||||
if (part === undefined) {
|
if (part === undefined) {
|
||||||
throw new Error('Email part could not be parsed.');
|
throw new NodeOperationError(this.getNode(), 'Email part could not be parsed.');
|
||||||
}
|
}
|
||||||
const parsedEmail = await parseRawEmail.call(this, part.body, dataPropertyAttachmentsPrefixName);
|
const parsedEmail = await parseRawEmail.call(this, part.body, dataPropertyAttachmentsPrefixName);
|
||||||
|
|
||||||
|
@ -337,7 +338,7 @@ export class EmailReadImap implements INodeType {
|
||||||
const part = lodash.find(message.parts, { which: 'TEXT' });
|
const part = lodash.find(message.parts, { which: 'TEXT' });
|
||||||
|
|
||||||
if (part === undefined) {
|
if (part === undefined) {
|
||||||
throw new Error('Email part could not be parsed.');
|
throw new NodeOperationError(this.getNode(), 'Email part could not be parsed.');
|
||||||
}
|
}
|
||||||
// Return base64 string
|
// Return base64 string
|
||||||
newEmail = {
|
newEmail = {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { createTransport } from 'nodemailer';
|
import { createTransport } from 'nodemailer';
|
||||||
|
@ -148,7 +149,7 @@ export class EmailSend implements INodeType {
|
||||||
const credentials = this.getCredentials('smtp');
|
const credentials = this.getCredentials('smtp');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const connectionOptions: SMTPTransport.Options = {
|
const connectionOptions: SMTPTransport.Options = {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
import {
|
import {
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
|
NodeApiError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +19,7 @@ export async function emeliaGraphqlRequest(
|
||||||
const response = await emeliaApiRequest.call(this, 'POST', '/graphql', body);
|
const response = await emeliaApiRequest.call(this, 'POST', '/graphql', body);
|
||||||
|
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
throw new Error(`Emelia error message: ${response.errors[0].message}`);
|
throw new NodeApiError(this.getNode(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@ -48,19 +49,9 @@ export async function emeliaApiRequest(
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return await this.helpers.request!.call(this, options);
|
return await this.helpers.request!.call(this, options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
if (error?.response?.body?.error) {
|
|
||||||
const { error: errorMessage } = error.response.body;
|
|
||||||
throw new Error(
|
|
||||||
`Emelia error response [${error.statusCode}]: ${errorMessage}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue