diff --git a/README.md b/README.md index 6f9f939..0bbad5c 100644 --- a/README.md +++ b/README.md @@ -461,7 +461,7 @@ Get real estate agent information from Redfin. - **1.1.0**: Crawler resource: initiate crawler jobs, get job status, and cancel jobs. - **1.2.0**: Structured Data Endpoints (SDEs) resource for Amazon, Google, Walmart, eBay, and Redfin. - **1.2.1**: Refactor SDE optional parameters into per-operation collections to satisfy the n8n community node validator. -- **1.2.2**: Publish via GitHub Actions with npm provenance attestation; bump `@n8n/node-cli` to `^0.29.1`. +- **1.2.2**: Publish via GitHub Actions with npm provenance attestation; bump `@n8n/node-cli` to `^0.29.1`; preserve original error types (e.g. `NodeOperationError`) when `continueOnFail` is off. ## More ScraperAPI Integrations diff --git a/nodes/ScraperApi/ScraperApi.node.ts b/nodes/ScraperApi/ScraperApi.node.ts index fce335f..008a9c3 100644 --- a/nodes/ScraperApi/ScraperApi.node.ts +++ b/nodes/ScraperApi/ScraperApi.node.ts @@ -3,9 +3,8 @@ import type { INodeExecutionData, INodeType, INodeTypeDescription, - JsonObject, } from 'n8n-workflow'; -import { NodeApiError, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow'; +import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow'; import { ApiResource } from './resources/api/ApiResource'; import { ApiOperations, ApiFields } from './resources/api/ApiDescription'; import { CrawlerResource } from './resources/crawler/CrawlerResource'; @@ -71,43 +70,40 @@ export class ScraperApi implements INodeType { sde: SdeResource, } as const; - for (let i = 0; i < items.length; i++) { - try { - const ResourceClass = resourceMap[resource as keyof typeof resourceMap]; - if (!ResourceClass) { - throw new NodeOperationError(this.getNode(), `Unknown resource type: ${resource}`); - } - - const resourceInstance = new ResourceClass(this); - const response = await resourceInstance.executeRequest(i); + const ResourceClass = resourceMap[resource as keyof typeof resourceMap]; + if (!ResourceClass) { + throw new NodeOperationError(this.getNode(), `Unknown resource type: ${resource}`); + } - returnData.push({ - json: { - resource, - response: { - body: response.body, - headers: response.headers, - statusCode: response.statusCode, - statusMessage: response.statusMessage, - }, + const executeOne = async (i: number): Promise => { + const resourceInstance = new ResourceClass(this); + const response = await resourceInstance.executeRequest(i); + return { + json: { + resource, + response: { + body: response.body, + headers: response.headers, + statusCode: response.statusCode, + statusMessage: response.statusMessage, }, - pairedItem: { - item: i, - }, - }); - } catch (error) { - if (this.continueOnFail()) { + }, + pairedItem: { item: i }, + }; + }; + + for (let i = 0; i < items.length; i++) { + if (this.continueOnFail()) { + try { + returnData.push(await executeOne(i)); + } catch (error) { returnData.push({ - json: { - error: error.message, - }, - pairedItem: { - item: i, - }, + json: { error: error.message }, + pairedItem: { item: i }, }); - continue; } - throw new NodeApiError(this.getNode(), error as JsonObject, { itemIndex: i }); + } else { + returnData.push(await executeOne(i)); } }