Skip to content

Return HTTP 400 for malformed date-range filter input - #42

Merged
turegjorup merged 2 commits into
developfrom
fix/date-range-filter-error-contract
Jul 8, 2026
Merged

Return HTTP 400 for malformed date-range filter input#42
turegjorup merged 2 commits into
developfrom
fix/date-range-filter-error-contract

Conversation

@turegjorup

Copy link
Copy Markdown
Contributor

Malformed date-range filter input now returns HTTP 400 instead of leaking as a 500.

Changes

  • DateRangeFilter resolves the client operator via a name lookup and throws ApiPlatform\Metadata\Exception\InvalidArgumentException on both invalid paths — a malformed between value and an unknown operator (field[foo]=…). The per-field throwOnInvalid flag is now honoured: when false the clause is skipped instead of throwing.
  • config/packages/api_platform.yaml: fix the stale exception_to_status mapping to the current ApiPlatform\Metadata\Exception\InvalidArgumentException namespace (the old ApiPlatform\Exception\InvalidArgumentException class no longer exists, so the mapping was inert).
  • Remove the now-dead classConstant.nameType entry from the PHPStan baseline (the dynamic DateLimit::{…} fetch is gone).
  • Unskip FilterErrorTest and extend it with the unknown-operator and non-date-value (Elasticsearch-rejected → ElasticIndexException → 400) cases.
  • Update the DateRangeFilterTest unit pins to the new behaviour.

Why

Two filter error paths leaked as HTTP 500: a malformed between threw PHP's native \InvalidArgumentException, and an unknown operator hit a raw \Error from DateLimit::{unknownKey}. Neither type was in exception_to_status. This is a prerequisite hardening step before the API Platform upgrade — malformed client input must surface as a 4xx, and the change is backwards-compatible (500 → 400 only).

DateRangeFilter threw PHP's native \InvalidArgumentException for a
malformed `between` value and a raw \Error for an unknown operator
(DateLimit::{unknownKey}). Neither is mapped in exception_to_status, so
both leaked as HTTP 500.

Resolve the operator via a name lookup and throw ApiPlatform's
InvalidArgumentException on both invalid paths, honouring the
per-field `throwOnInvalid` flag (skip the clause when false). Fix the
stale exception_to_status mapping to the current
ApiPlatform\Metadata\Exception\InvalidArgumentException namespace so it
maps to 400. Unskip FilterErrorTest and extend it with the
unknown-operator and non-date-value (Elasticsearch-rejected) cases.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.68%. Comparing base (d6f37ac) to head (2550dd3).
⚠️ Report is 9 commits behind head on develop.

Additional details and impacted files
@@              Coverage Diff              @@
##             develop      #42      +/-   ##
=============================================
+ Coverage      71.89%   72.68%   +0.78%     
- Complexity       226      232       +6     
=============================================
  Files             29       29              
  Lines            637      648      +11     
=============================================
+ Hits             458      471      +13     
+ Misses           179      177       -2     
Flag Coverage Δ
unittests 72.68% <100.00%> (+0.78%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@turegjorup turegjorup self-assigned this Jul 8, 2026
@turegjorup
turegjorup merged commit e251546 into develop Jul 8, 2026
12 checks passed
@turegjorup
turegjorup deleted the fix/date-range-filter-error-contract branch July 8, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants