Skip to content

AutoscaledPool.notify() called from a request handler aborts the whole crawl #4081

Description

@barjin

notify() is just setImmediate(this._maybeRunTask), so calling it from a request handler runs the pool loop in that handler's @apify/timeout context. If the handler has overrun requestHandlerTimeoutSecs, that context is already aborted, and the first tryCancel() in _runTaskFunction sits before its try/catch — so the whole AutoscaledPool rejects instead of one request failing.

import { BasicCrawler, sleep } from 'crawlee';

const crawler = new BasicCrawler({
    keepAlive: true,                 // pool stays idle-but-alive once the queue drains
    maxRequestRetries: 0,
    requestHandlerTimeoutSecs: 1,
    async requestHandler({ request, crawler }) {
        if (!request.url.endsWith('/orphan')) return;

        await sleep(2000);                                         // overruns the 1s timeout
        await crawler.addRequests(['https://x.test/never-crawled']);
        await crawler.autoscaledPool.notify();                     // pool loop, aborted context
    },
    failedRequestHandler() {},
});

await crawler.run(['https://x.test/orphan']).catch((e) => console.log(`crawl died: ${e.constructor.name}: ${e.message}`));

const { requestsFinished, requestsFailed } = crawler.stats.state;
console.log(`accounted for ${requestsFinished + requestsFailed}/2 requests`);
InternalTimeoutError: Promise handler has been canceled due to a timeout
    at tryCancel (@apify/timeout/cjs/index.cjs:43:11)
    at BasicCrawler._runTaskFunction (@crawlee/basic/internals/basic-crawler.js:1049:33)
    at async AutoscaledPool._maybeRunTask (@crawlee/core/autoscaling/autoscaled_pool.js:535:17)

crawl died: InternalTimeoutError: Promise handler has been canceled due to a timeout
accounted for 1/2 requests

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-toolingIssues with this label are in the ownership of the tooling team.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions