dry-rb / dry-schema

Coercion and validation for data structures
https://dry-rb.org/gems/dry-schema
MIT License
424 stars 110 forks source link

Exception silenced when raised from nested schema #445

Open Yv-vY opened 1 year ago

Yv-vY commented 1 year ago

Behavior is inconsistent between "flat" and nested schema when an exception occur.

To reproduce

NestedSchema = Dry::Schema.Params do
  required(:value).filter(format?: /^\d+$/).value(:float)
end

ParentSchema = Dry::Schema.Params do
  required(:data).hash(NestedSchema)
end

# KO: filter() should fail as it expect a string, got no exception
ParentSchema.call({data: {value: 123}})
=> #<Dry::Schema::Result{:data=>{:value=>123.0}} errors={} path=[]>

Expected behavior

I would expect the exception to be forwarded from the nested schema and not silenced as it is the case with a "flat" schema:

FlatSchema = Dry::Schema.Params do
  required(:data).hash do
    required(:value).filter(format?: /^\d+$/).value(:float)
  end
end

# OK: filter() fails as it expects a string and gets a numeric -> exception
FlatSchema.call({data: {value: 123}})
=> [..]/.gem/ruby/3.0.2/gems/dry-logic-1.5.0/lib/dry/logic/predicates.rb:226:in `match?': no implicit conversion of Integer into String (TypeError)
    [...]

Additionaly we can wonder why the filter call fails if we provide a value that is actually matching the coercion.

My environment

Affects my production application: YES Ruby version: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) OS: Fedora 37 beta [aarch64-linux]

Yv-vY commented 1 year ago

BTW we can see that the value has been coerced when using the nested schema.

solnic commented 1 year ago

Thanks for reporting this. Looks like filters are not added when an external schema is passed to hash macro.