Skip to content

Rescue TypeError in date/time and numeric filter converters - #595

Draft
justincampbell wants to merge 1 commit into
AaronLasseigne:mainfrom
justincampbell:fix/datetime-typeerror
Draft

Rescue TypeError in date/time and numeric filter converters#595
justincampbell wants to merge 1 commit into
AaronLasseigne:mainfrom
justincampbell:fix/datetime-typeerror

Conversation

@justincampbell

Copy link
Copy Markdown

Problem

AbstractDateTimeFilter#convert_string and AbstractNumericFilter#safe_converter only rescue ArgumentError. When an input object has to_str / to_int that returns a non-String / non-Integer (legal Ruby, though it violates the implicit-conversion contract), the underlying parse raises TypeError, which escapes the filter and propagates out of .run as an unhandled exception:

class DateCheck < ActiveInteraction::Base
  date :d
  def execute; d; end
end

class BadStr
  def to_str; :not_a_string; end
  def respond_to?(m, *); m == :to_str || super; end
end

DateCheck.run(d: BadStr.new)
# => TypeError: no implicit conversion of Symbol into String

This breaks the contract that .run returns a result — even for bad input, it should surface a validation error, not raise. The same pattern exists in AbstractNumericFilter#safe_converter where Integer(non_int) / Float(non_str) / BigDecimal(non_str) raise TypeError that isn't caught.

Fix

Rescue TypeError alongside ArgumentError in both filters, so non-conforming to_str / to_int values surface as :invalid_type filter errors — consistent with how unparseable strings are already handled.

Test plan

  • Added specs in date_filter_spec.rb and integer_filter_spec.rb that construct values with a to_str returning a Symbol. Both specs fail on main with uncaught TypeError and pass with this change.
  • Full bundle exec rspec suite passes (1088 examples, 0 failures).
  • The two new specs were verified to fail against unpatched code before restoring the fix.

Marking draft while maintainers review the approach.

AbstractDateTimeFilter#convert_string and AbstractNumericFilter#safe_converter
only rescued ArgumentError. When an input object's to_str / to_int returns
a non-String / non-Integer (violating the implicit-conversion contract but
legal Ruby), the underlying parse raises TypeError, which escapes the filter
and propagates out of .run as an unhandled exception — violating the contract
that .run returns a result with errors rather than raising for bad input.

Rescue TypeError alongside ArgumentError so these values surface as
:invalid_type filter errors, consistent with other unparseable inputs.
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.

1 participant