Fix filter_tasks_by_metadata masking connection/timeout errors - #3317
prabhaharanv wants to merge 2 commits into
Conversation
filter_tasks_by_metadata caught bare Exception and read e.http_code, which is only defined on ServiceException. When _request raised a connection or timeout error (propagated unwrapped from its final retry), reading e.http_code raised AttributeError, masking the real failure. Catch ServiceException only, matching every other handler in the file, so connection and timeout errors propagate unchanged. Add regression tests covering the non-service error, 404, and other-service-error paths. Fixes Netflix#3316
Greptile SummaryThis PR corrects exception handling for metadata task filtering.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| metaflow/plugins/metadata_providers/service.py | Narrows endpoint error handling to service-level exceptions while preserving existing 404 translation and other service failures. |
| test/unit/test_service_metadata_provider.py | Adds focused regression coverage for transport, 404, and non-404 exception paths. |
Reviews (2): Last reviewed commit: "Merge branch 'master' into fix/filter-ta..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3317 +/- ##
=========================================
Coverage ? 30.60%
=========================================
Files ? 381
Lines ? 52639
Branches ? 9287
=========================================
Hits ? 16110
Misses ? 35330
Partials ? 1199 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Shriprasad-P
left a comment
There was a problem hiding this comment.
Review
PR: Fix filter_tasks_by_metadata masking connection/timeout errors
Touched: metaflow/plugins/metadata_providers/service.py, test/unit/test_service_metadata_provider.py
- Addresses a concrete correctness/reliability issue based on the title and diff.
- Includes or touches tests — good for locking the behavior.
- Size looks manageable (+57/-3).
Commenting as a drive-by reviewer after reading the diff. Happy to look again if maintainers want a deeper pass on a specific file.
PR Type
Summary
filter_tasks_by_metadatacaught bareExceptionand reade.http_code, whichonly exists on
ServiceException. A connection/timeout error from_requesttherefore raised
AttributeError, masking the real failure. Narrow the catch toServiceException.Issue
Fixes #3316
Reproduction
Runtime: local (Client / metadata service call)
Commands to run:
# Mechanism (no live service needed) — reproduced in the added unit test: python -m pytest test/unit/test_service_metadata_provider.py -vWith
METAFLOW_SERVICE_URLpointed at an unreachable host, any Client call thatroutes through
filter_tasks_by_metadatafails withAttributeErrorinstead ofthe underlying connection error.
Where evidence shows up: the exception raised to the caller / test output
Before (real error is masked)
After (real error propagates)
Root Cause
_requestre-raises transport errors (requestsConnectionError/Timeout)unwrapped on its final retry — the bare
except: ... raiseat the end of itsretry loop does not convert them to
ServiceException.filter_tasks_by_metadatathen caught bare
Exceptionand accessede.http_code, an attribute definedonly on
ServiceException(set in its__init__). For any non-service error,that attribute access raised
AttributeError, discarding the original exception.Every other handler in this file already catches
ServiceExceptionspecifically.Why This Fix Is Correct
Only
ServiceExceptioncarrieshttp_code, and only a service-level 404 shouldbe translated into the "upgrade your metadata service" message. Narrowing to
except ServiceExceptionrestores that invariant: service errors are handled asbefore (404 →
MetaflowInternalError, others re-raised), and transport errorspropagate unchanged instead of being turned into an
AttributeError. The changeis minimal and brings this handler in line with the rest of the file.
Failure Modes Considered
ServiceException(including the 404 case) is still caught and handled identically; the added
tests cover the 404 and non-404 service paths.
ConnectionError/Timeoutpropagate to the caller (the prior behavior onlyever produced an
AttributeError, never a handled result), so no previouslyhandled path is lost.
raise ewas changed to a bareraiseto preserve theoriginal traceback.
Tests
New
test/unit/test_service_metadata_provider.py:test_filter_tasks_by_metadata_propagates_non_service_exception— fails beforethe fix (raises
AttributeError), passes after (propagatesConnectionError).test_filter_tasks_by_metadata_missing_endpoint_raises_internal_error— 404 →MetaflowInternalError.test_filter_tasks_by_metadata_reraises_other_service_exception— non-404ServiceExceptionpropagates.Non-Goals
No change to
_request's retry/raise behavior or to any other handler; scope islimited to the exception type caught in
filter_tasks_by_metadata.AI Tool Usage
I found this bug (among several others) during independent analysis of the Client
API and metadata-service internals a few months ago, and noted that every other
handler in
service.pyusesexcept ServiceExceptionwhile this one used bareException. I used Claude to help draft the one-line fix, the regression tests,and this description. I reviewed and understand the change, verified the
masking behavior and the fix myself, and can explain the root cause and the
failure modes considered.