diff --git a/src/input.ts b/src/input.ts index cb7597b..f499ab5 100644 --- a/src/input.ts +++ b/src/input.ts @@ -19,6 +19,7 @@ import type { SERPProxyGroup, UrlToMarkdownInput, } from './types.js'; +import { abortRun } from './utils.js'; /** * Processes the input and returns an array of crawler settings. This is ideal for startup of STANDBY mode @@ -27,7 +28,7 @@ import type { export async function processStandbyInput(originalInput: Partial) { const { input, searchCrawlerOptions, contentScraperSettings } = await processInputInternal(originalInput, true); - const proxy = await Actor.createProxyConfiguration(input.proxyConfiguration); + const proxy = await createContentProxyConfiguration(input.proxyConfiguration); const contentCrawlerOptions: ContentCrawlerOptions[] = [ createPlaywrightCrawlerOptions(input, proxy), createCheerioCrawlerOptions(input, proxy), @@ -42,7 +43,7 @@ export async function processStandbyInput(originalInput: Partial) { export async function processInput(originalInput: Partial) { const { input, searchCrawlerOptions, contentScraperSettings } = await processInputInternal(originalInput); - const proxy = await Actor.createProxyConfiguration(input.proxyConfiguration); + const proxy = await createContentProxyConfiguration(input.proxyConfiguration); const contentCrawlerOptions: ContentCrawlerOptions = input.scrapingTool === 'raw-http' ? createCheerioCrawlerOptions(input, proxy, false) : createPlaywrightCrawlerOptions(input, proxy, false); @@ -210,6 +211,14 @@ async function processUrlToMarkdownInput(input: Partial): Pr return validatedInput; } +async function createContentProxyConfiguration(proxyConfiguration: ProxyConfigurationOptions) { + try { + return await Actor.createProxyConfiguration(proxyConfiguration); + } catch (e) { + return abortRun(`Cannot use Apify Proxy for scraping the target pages: ${(e as Error).message}`); + } +} + function createPlaywrightCrawlerOptions( input: Input, proxy: ProxyConfiguration | undefined, diff --git a/src/utils.ts b/src/utils.ts index 19e2892..77f7107 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -47,6 +47,22 @@ export function isActorStandby(): boolean { return Actor.getEnv().metaOrigin === 'STANDBY'; } +/** + * Aborts the run with a terminal status message, instead of crashing or failing it. + */ +export async function abortRun(statusMessage: string): Promise { + log.error(statusMessage); + + if (!Actor.isAtHome()) { + process.exit(1); + } + + // Aborting gracefully buys the 30 seconds that the teardown needs before the container is stopped. + await Actor.abort(Actor.getEnv().actorRunId!, { statusMessage, gracefully: true }); + await Actor.exit({ exit: false }); + process.exit(0); +} + /** * Extracts the calling end-user's authorization from the x-apify-user-authorization header. * Node lower-cases header names, and the header could theoretically arrive as a string array.