Problem
WG21Index.refresh() in src/paperscout/sources.py returns an empty self.papers dict on all failure paths — network error, timeout, rate limit, parse failure, and "no data available" — without raising or propagating a discriminated error. Callers (Scheduler.seed() and Scheduler.poll_once()) receive the same empty dict regardless of root cause, preventing differentiated retry logic. The _download() helper logs a FailureCategory but this structured signal is consumed by log.warning/error and discarded from the return path.
Acceptance Criteria
Implementation Notes
- Primary file:
src/paperscout/sources.py — modify refresh() and _download()
- Error taxonomy:
src/paperscout/errors.py — add IndexRefreshError(category: FailureCategory)
- Caller updates:
src/paperscout/monitor.py — handle discriminated result
- Tests:
tests/test_sources.py, tests/test_scout.py, tests/test_monitor.py
References
src/paperscout/errors.py (existing FailureCategory enum)
src/paperscout/sources.py (download error handlers)
Problem
WG21Index.refresh()insrc/paperscout/sources.pyreturns an emptyself.papersdict on all failure paths — network error, timeout, rate limit, parse failure, and "no data available" — without raising or propagating a discriminated error. Callers (Scheduler.seed()andScheduler.poll_once()) receive the same empty dict regardless of root cause, preventing differentiated retry logic. The_download()helper logs aFailureCategorybut this structured signal is consumed bylog.warning/errorand discarded from the return path.Acceptance Criteria
refresh()raises (or returns a result object carrying) a discriminated error distinguishing at leastTIMEOUT,RATE_LIMIT,NETWORK, andCONFIGURATIONcategoriesConfigurationErrorImplementation Notes
src/paperscout/sources.py— modifyrefresh()and_download()src/paperscout/errors.py— addIndexRefreshError(category: FailureCategory)src/paperscout/monitor.py— handle discriminated resulttests/test_sources.py,tests/test_scout.py,tests/test_monitor.pyReferences
src/paperscout/errors.py(existingFailureCategoryenum)src/paperscout/sources.py(download error handlers)