{"record":{"id":"0e311252b3011aca","repo":"apify/crawlee","slug":"this-getmessagefromerror-error","errorCode":null,"errorMessage":"${this.getMessageFromError(error)}","messagePattern":"\\$\\{this\\.getMessageFromError\\(error\\)\\}","errorType":"exception","errorClass":"SessionError","httpStatus":null,"severity":"error","filePath":"packages/browser-crawler/src/internals/browser-crawler.ts","lineNumber":821,"sourceCode":"\n        // Fire-and-forget: no user code will run on this page after a failed navigation.\n        // Swallow rejections: the page may already be detached.\n        void page.evaluate(() => window.stop()).catch(() => {});\n\n        if (isNavigationTimeoutError(error)) {\n            session?.markBad();\n            // The driver was handed the remaining window (usually shorter than `navigationTimeoutSecs` once the\n            // hooks have run), so it names that value in its own error; report the configured window instead.\n            throw new TimeoutError(`Navigation timed out after ${this.#navigationTimeoutMillis / 1000} seconds.`);\n        }\n    }\n\n    /**\n     * Transforms proxy-related errors to `SessionError`.\n     */\n    private throwIfProxyError(error: Error) {\n        if (this.isProxyError(error)) {\n            throw new SessionError(this.getMessageFromError(error) as string);\n        }\n    }\n\n    protected abstract navigationHandler(\n        crawlingContext: BrowserCrawlingContext<Page, Response>,\n        gotoOptions: GoToOptions,\n    ): Promise<Context['response'] | null | undefined>;\n\n    private async processResponse(\n        response: Response | undefined,\n        crawlingContext: BrowserCrawlingContext,\n    ): Promise<void> {\n        const { session, request, page } = crawlingContext;\n\n        if (typeof response === 'object' && typeof response.status === 'function') {\n            const status: number = response.status();\n\n            this.statistics.registerStatusCode(status);","sourceCodeStart":803,"sourceCodeEnd":839,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/browser-crawler/src/internals/browser-crawler.ts#L803-L839","documentation":"`throwIfProxyError()` checks whether a navigation failure was caused by the proxy (via `isProxyError`) and, if so, converts it into a `SessionError` with the original message. This tells the crawler the failure is proxy-related so the session/proxy is retired and the request retried, instead of counting it as a normal request error.","triggerScenarios":"`page.goto()` (or the underlying network stack) rejects with a proxy-specific error — e.g. `ERR_PROXY_CONNECTION_FAILED`, proxy authentication required (407), or tunnel connection refused — while navigating through a `proxyUrl`/`proxyConfiguration` with a dead or misconfigured proxy.","commonSituations":"Proxy server down or DNS unresolvable; wrong credentials in `http://user:pass@host:port` proxy URLs; proxy rate-limited or banned; using an expired paid proxy subscription; Docker/CI environments where the proxy host is unreachable.","solutions":["Verify the proxy is reachable: `curl -x http://host:port https://example.com` — fix or replace dead proxies","Check credentials embedded in the proxy URL and rotate them if the proxy reports auth failures","Configure multiple `proxyUrls` in `ProxyConfiguration` so failed proxies are rotated away from","Ensure a session pool is used so the bad session/proxy combination is retired automatically"],"exampleFix":"// before\nnew PlaywrightCrawler({ proxyUrls: ['http://10.0.0.5:8080'] }); // proxy down\n// after\nconst proxyConfiguration = await ProxyConfiguration.create({\n    proxyUrls: ['http://proxy1:8080', 'http://proxy2:8080'], // rotation provides fallback\n});\nnew PlaywrightCrawler({ proxyConfiguration });","handlingStrategy":"validation","validationCode":"// Verify proxy reachability before starting the crawl:\nconst res = await fetch('https://api.ipify.org', {\n    agent: new HttpsProxyAgent(proxyUrl),\n    signal: AbortSignal.timeout(10_000),\n});\nconsole.log('proxy OK, egress IP:', await res.text());","typeGuard":"function isProxySessionError(e: unknown): e is SessionError {\n    return e instanceof SessionError && /proxy|ERR_PROXY|407|tunnel/i.test(e.message);\n}","tryCatchPattern":"crawler.failedRequestHandler = async ({ request, error }) => {\n    if (error instanceof SessionError && /proxy/i.test(error.message)) {\n        log.error(`Proxy failed for ${request.url}: ${error.message} — rotate proxyUrls`);\n    }\n};","preventionTips":["Health-check proxies (curl -x ...) before long crawls","Provide several proxyUrls so ProxyConfiguration can rotate","Validate credentials in proxy URLs and monitor for 407 responses"],"tags":["proxy","session","network","browser-crawler"],"backgroundTag":"proxy-connection-failed","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}