If a model is given an object where the transform_keys block has to change the key, then the error handling is broken. It gives an error about the error.
To Reproduce
require "dry-types"
require "dry-struct"
require 'json'
module Types
include Dry.Types(default: :strict)
NBoolean = Bool.optional.default(nil)
end
class BaseModel < Dry::Struct
transform_keys(&:to_sym)
end
class OtherThing < BaseModel
attribute :somebool, Types::NBoolean.default(true.freeze)
end
class Thing < BaseModel
attribute :services, Types::Hash.map(Types::String, OtherThing)
end
data = {
services: {
foo: {
somebool: "not a boolean"
}
}
}
# stringify the keys
data = JSON.parse(JSON.generate(data))
puts Thing.new(data).inspect
Results in the following exception:
/gems/dry-types-1.5.1/lib/dry/types/errors.rb:59:in `map': undefined method `message' for "[OtherThing.new] \\"not a boolean\\" (String) has invalid type for :somebool violates constraints (type?(FalseClass, \\"not a boolean\\") failed)":String (NoMethodError)
errors.map(&:message).join(", ")
^^^^
from /gems/dry-types-1.5.1/lib/dry/types/errors.rb:59:in `message'
from /gems/dry-types-1.5.1/lib/dry/types/map.rb:56:in `block in call_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/map.rb:78:in `try'
from /gems/dry-types-1.5.1/lib/dry/types/map.rb:55:in `call_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/schema/key.rb:49:in `call_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/schema.rb:328:in `block in resolve_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `each'
from /gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `resolve_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/schema.rb:62:in `call_unsafe'
from /gems/dry-types-1.5.1/lib/dry/types/constructor.rb:87:in `call_unsafe'
from /gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new'
from spec/dry_error_pr.rb:34:in `<main>'
Expected behavior
I would expect to get the proper error chain for my bogus boolean:
(When I comment out the JSON line at the end, and run it I get:
/gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:332:in `rescue in block in resolve_unsafe': [Thing.new] {:foo=>{:somebool=>"not a boolean"}} (Hash) has invalid type for :services violates constraints (:foo violates constraints (type?(String, :foo) failed) failed) (Dry::Struct::Error)
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:327:in `block in resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `each'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:62:in `call_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/constructor.rb:87:in `call_unsafe'
from /gems/3.1.0/gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new'
from spec/dry_error_pr.rb:31:in `<main>'
/gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:332:in `rescue in block in resolve_unsafe': {:foo=>{:somebool=>"not a boolean"}} (Hash) has invalid type for :services violates constraints (:foo violates constraints (type?(String, :foo) failed) failed) (Dry::Types::SchemaError)
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:327:in `block in resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `each'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:62:in `call_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/constructor.rb:87:in `call_unsafe'
from /gems/3.1.0/gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new'
from spec/dry_error_pr.rb:31:in `<main>'
/gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/map.rb:56:in `block in call_unsafe': :foo violates constraints (type?(String, :foo) failed) (Dry::Types::MapError)
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/map.rb:78:in `try'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/map.rb:55:in `call_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema/key.rb:49:in `call_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:328:in `block in resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `each'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:322:in `resolve_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/schema.rb:62:in `call_unsafe'
from /gems/3.1.0/gems/dry-types-1.5.1/lib/dry/types/constructor.rb:87:in `call_unsafe'
from /gems/3.1.0/gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new'
from spec/dry_error_pr.rb:31:in `<main>'
Describe the bug
If a model is given an object where the
transform_keys
block has to change the key, then the error handling is broken. It gives an error about the error.To Reproduce
Results in the following exception:
Expected behavior
I would expect to get the proper error chain for my bogus boolean:
(When I comment out the JSON line at the end, and run it I get:
My environment