fix: complete SessionError lifecycle and honor reclaim forefront - #2105
fix: complete SessionError lifecycle and honor reclaim forefront#2105Ayush7614 wants to merge 1 commit into
Conversation
Honor error_handler replacement requests for SessionError, retire blocked sessions when rotations are exhausted, propagate AdaptivePlaywright static SessionError for rotation instead of browser fallback, and reclaim retries with request.forefront for tiered-proxy priority.
There was a problem hiding this comment.
🟡 Not ready to approve
The SessionError path currently leaves requests in an inconsistent lifecycle state and misses retry/error tracking in one replacement branch, which can lead to incorrect persisted request metadata and statistics.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR completes the SessionError lifecycle in BasicCrawler/AdaptivePlaywrightCrawler and ensures retry reclaiming respects request queue priority (forefront) so tiered-proxy retries stay at the front of the queue.
Changes:
- Honor
error_handlerreturn values forSessionError, wrap handler exceptions consistently, and retire sessions when rotations are exhausted. - Re-raise
SessionErrorfrom the adaptive crawler’s static path to trigger session rotation instead of falling through to the browser. - Pass
forefront=request.forefrontintoreclaim_requestso priority retries preserve queue ordering.
File summaries
| File | Description |
|---|---|
src/crawlee/crawlers/_basic/_basic_crawler.py |
Updates retry reclaim behavior to honor forefront, and refines SessionError handling (rotation/retire + error_handler honoring). |
src/crawlee/crawlers/_adaptive_playwright/_adaptive_playwright_crawler.py |
Ensures static-path SessionError propagates to enable session rotation rather than browser fallback with the same session. |
tests/unit/crawlers/_basic/test_basic_crawler.py |
Adds unit tests covering SessionError error_handler replacement, session retirement on exhausted rotations, and forefront reclaim behavior. |
tests/unit/crawlers/_adaptive_playwright/test_adaptive_playwright_crawler.py |
Adds a unit test asserting static SessionError propagation triggers session rotation and prevents browser fallback. |
Review details
Suppressed comments (1)
src/crawlee/crawlers/_basic/_basic_crawler.py:1504
- When session rotations are exhausted, the request is marked as handled without setting its final state to ERROR. This leaves failed requests in REQUEST_HANDLER state in storage, which diverges from the normal error path (where the request is set to RequestState.ERROR before marking handled).
else:
# Exhausted rotations: retire the blocked session so it is not reused from the pool.
session.retire()
await self._mark_request_as_handled(request)
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| if not session: | ||
| raise RuntimeError('SessionError raised in a crawling context without a session') from session_error | ||
|
|
||
| new_request = None |
| if new_request is not None and new_request != request: | ||
| await request_manager.add_request(new_request) | ||
| await self._mark_request_as_handled(request) | ||
| session.retire() | ||
| return |
Summary
SessionErrorpath: honorerror_handlerreplacement requests (same as regular errors), wrap handler exceptions inUserDefinedErrorHandlerError, andretire()the blocked session when rotations are exhausted.SessionErrorfrom the static sub-crawler instead of falling through to the browser with the same blocked session.reclaim_requestnow passesforefront=request.forefrontso tiered-proxy priority retries actually stay at the front of the queue.Why
error_handlercould replace a request on normal failures but its return value was discarded forSessionError. Exhausted rotations left blocked sessions usable in the pool. Adaptive staticSessionErrorwas only logged, so a 403/blocked session could be reused for the browser fallback. Tiered proxies setrequest.forefront = Trueon retry, but reclaim always used the defaultforefront=False.Test plan
test_session_error_handler_can_replace_requesttest_session_retired_when_rotations_exhaustedtest_reclaim_uses_request_forefront_flagtest_static_session_error_propagates_for_rotation