diff --git a/docs/integrations/creating-nodes/build/reference/error-handling.md b/docs/integrations/creating-nodes/build/reference/error-handling.md new file mode 100644 index 000000000..e4938d33b --- /dev/null +++ b/docs/integrations/creating-nodes/build/reference/error-handling.md @@ -0,0 +1,141 @@ +--- +#https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4 +contentType: reference +--- + +# Error handling in n8n nodes + +Proper error handling is crucial for creating robust n8n nodes that provide clear feedback to users when things go wrong. n8n provides two specialized error classes to handle different types of failures in node implementations: + +- [**`NodeApiError`**](#nodeapierror): For API-related errors and external service failures +- [**`NodeOperationError`**](#nodeoperationerror): For operational errors, validation failures, and configuration issues + +## NodeApiError + +Use `NodeApiError` when dealing with external API calls and HTTP requests. This error class is specifically designed to handle API response errors and provides enhanced features for parsing and presenting API-related failures such as: + + * HTTP request failures + * external API errors + * authentication/authorization failures + * rate limiting errors + * service unavailable errors + +Initialize new `NodeApiError` instances using the following pattern: + +```typescript +new NodeApiError(node: INode, errorResponse: JsonObject, options?: NodeApiErrorOptions) +``` + +### Common usage patterns + +For basic API request failures, catch the error and wrap it in `NodeApiError`: + +```typescript +try { + const response = await this.helpers.requestWithAuthentication.call( + this, + credentialType, + options + ); + return response; +} catch (error) { + throw new NodeApiError(this.getNode(), error as JsonObject); +} +``` + +Handle specific HTTP status codes with custom messages: + +```typescript +try { + const response = await this.helpers.requestWithAuthentication.call( + this, + credentialType, + options + ); + return response; +} catch (error) { + if (error.httpCode === "404") { + const resource = this.getNodeParameter("resource", 0) as string; + const errorOptions = { + message: `${ + resource.charAt(0).toUpperCase() + resource.slice(1) + } not found`, + description: + "The requested resource could not be found. Please check your input parameters.", + }; + throw new NodeApiError( + this.getNode(), + error as JsonObject, + errorOptions + ); + } + + if (error.httpCode === "401") { + throw new NodeApiError(this.getNode(), error as JsonObject, { + message: "Authentication failed", + description: "Please check your credentials and try again.", + }); + } + + throw new NodeApiError(this.getNode(), error as JsonObject); +} +``` + +## NodeOperationError + +Use `NodeOperationError` for: + + * operational errors + * validation failures + * configuration issues that aren't related to external API calls + * input validation errors + * missing required parameters + * data transformation errors + * workflow logic errors + + Initialize new `NodeOperationError` instances using the following pattern: + +```typescript +new NodeOperationError(node: INode, error: Error | string | JsonObject, options?: NodeOperationErrorOptions) +``` + +### Common usage patterns + +Use `NodeOperationError` for validating user inputs: + +```typescript +const email = this.getNodeParameter("email", itemIndex) as string; + +if (email.indexOf("@") === -1) { + const description = `The email address '${email}' in the 'email' field isn't valid`; + throw new NodeOperationError(this.getNode(), "Invalid email address", { + description, + itemIndex, // for multiple items, this will link the error to the specific item + }); +} +``` + +When processing multiple items, include the item index for better error context: + +```typescript +for (let i = 0; i < items.length; i++) { + try { + // Process item + const result = await processItem(items[i]); + returnData.push(result); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ + json: { error: error.message }, + pairedItem: { item: i }, + }); + continue; + } + + throw new NodeOperationError(this.getNode(), error as Error, { + description: error.description, + itemIndex: i, + }); + } +} +``` diff --git a/docs/integrations/creating-nodes/plan/node-ui-design.md b/docs/integrations/creating-nodes/plan/node-ui-design.md index 4b0104b42..7f816b4dd 100644 --- a/docs/integrations/creating-nodes/plan/node-ui-design.md +++ b/docs/integrations/creating-nodes/plan/node-ui-design.md @@ -106,6 +106,8 @@ Add validation rules to fields if possible. For example, check for valid email p When displaying errors, make sure only the main error message displays in the red error title. More information should go in **Details**. +Refer to [Node Error Handling](/integrations/creating-nodes/build/reference/error-handling.md) for more information. + #### Toggles * Tooltips for binary states should start with something like **Whether to . . . **. diff --git a/nav.yml b/nav.yml index c1d4195de..ca4836c35 100644 --- a/nav.yml +++ b/nav.yml @@ -1130,6 +1130,7 @@ nav: - integrations/creating-nodes/build/reference/index.md - Node UI elements: integrations/creating-nodes/build/reference/ui-elements.md - Code standards: integrations/creating-nodes/build/reference/code-standards.md + - Error handling: integrations/creating-nodes/build/reference/error-handling.md - Versioning: integrations/creating-nodes/build/reference/node-versioning.md - File structure: integrations/creating-nodes/build/reference/node-file-structure.md - Base files: