dry-struct icon indicating copy to clipboard operation
dry-struct copied to clipboard

`Dry::Types::ConstraintError` not propagated when originating from inside a `Dry::Types::Map`

Open hovsater opened this issue 11 months ago • 0 comments

Describe the bug

Given the following code:

module Types
  include Dry.Types

  Fruit = String.enum("apple", "banana", "pear")
end

class FruitScore < Dry::Struct
  attribute :fruit, Types::Fruit
  attribute :score, Types::Integer.constrained(gteq: 1, lteq: 10)
end

class FruitScoreboard < Dry::Struct
  attribute :scores, Types::Map(Types::String, Types::Array.of(FruitScore))
end

one would expect the following input:

FruitScoreboard.new(scores: { "john" => [{ fruit: "lemon", score: 1 }] })

to generate an error message related to the constraint being violated. Instead, we get the following error message:

/gems/dry-types-1.7.0/lib/dry/types/nominal.rb:122:in `failure': error must be a CoercionError (ArgumentError)

        raise ArgumentError, "error must be a CoercionError" unless error.is_a?(CoercionError)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The error originate from here:

https://github.com/dry-rb/dry-types/blob/ffde4175a833c6911cc889e7b1b4717bc712d3be/lib/dry/types/nominal.rb#L121-L125

and I assume error received is a MultipleError judging by this code:

https://github.com/dry-rb/dry-types/blob/ffde4175a833c6911cc889e7b1b4717bc712d3be/lib/dry/types/map.rb#L132-L136

Should the check:

raise ArgumentError, "error must be a CoercionError" unless error.is_a?(CoercionError)

perhaps be changed into this?

raise ArgumentError, "error must be a CoercionError" unless error <= CoercionError

Expected behavior

I expect a Dry::Struct::Error to be raised that propagates the actual Dry::Types::ConstraintError error.

My environment

  • Affects my production application: YES
  • Ruby version: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
  • OS: macOS 14.3 (23D56)

hovsater avatar Feb 28 '24 13:02 hovsater