fix: don't raise ArgumentError when filters map has non-integer keys#655
Conversation
Flop.Meta.filters_to_list/1 called String.to_integer/1 directly on
every key of the filters map, raising ArgumentError on any non-integer
key (e.g. ?filters[name]=value). This also broke
Flop.Meta.with_errors/3, preventing Flop from constructing the
{:error, %Flop.Meta{}} tuple it normally returns for invalid filter
shapes.
Entries with non-integer keys are now dropped silently, consistent
with how other malformed filter inputs are handled.
| |> Enum.flat_map(fn {index, filter} -> | ||
| case parse_filter_index(index) do | ||
| {:ok, n} -> [{n, filter}] | ||
| :error -> [] |
There was a problem hiding this comment.
Wouldn't you want to see the original parameters in the error struct?
There was a problem hiding this comment.
Good point 👍
filters_to_list/1 is only called from with_errors/3, so its output ends up in meta.params. Silently dropping malformed entries hides exactly the information the caller needs to debug (e.g, "here's the filters[name]=foo you sent, here's why it's wrong"...etc).
Updated (commit: 1ad0d9f): when any key can't be parsed as integer, leave the input filters untouched rather than partially transforming it. The happy path (all integer indexed keys) unchanged, and a malformed map goes into meta.params so the caller sees exactly what they sent.
There was a problem hiding this comment.
Hi @woylie Are you happy with the update/change?
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #655 +/- ##
==========================================
- Coverage 84.45% 84.41% -0.05%
==========================================
Files 15 15
Lines 1023 1033 +10
==========================================
+ Hits 864 872 +8
- Misses 159 161 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary
Flop.Meta.filters_to_list/1callsString.to_integer/1directly on every key of thefiltersmap, raisingArgumentErroron any non-integer key. This causes Flop to crash with an uncaught exception before it can return its documented{:error, %Flop.Meta{}}validation tuple.The crash also affects Flop's own error-construction path:
Flop.Meta.with_errors/3callsfilters_to_list/1when building theparamsfield of an error meta, so once a malformed map reaches Flop, even constructing the error tuple re-raises. That makes it impossible for callers to recover via the publicFlop.validate/2/Flop.validate_and_run/3contract.Repro
Observed in production from a misconfigured client sending
?filters[transport_type_code]=SEA. The map-keyed-by-field name form is invalid input, but it should surface as a validation error rather than an uncaught exception.Change
Replace
String.to_integer/1with aparse_filter_index/1helper that accepts integer keys as-is and usesInteger.parse/1for string keys, requiring the entire string to parse. Entries with non-integer keys are dropped silently from the resulting list - matching how the fallthrough clause already treats filters values that aren't in the indexed-map shape. Behaviour for all currently-valid inputs is unchanged.Tests
Added in
test/base/flop/meta_test.exs:Flop.validate/2returns{:error, %Flop.Meta{}}for a field-name-keyed filter map