dry-rb / dry-rb/dry-types

Unexpected error raised from Sum type

Open
#439 7 comments 0 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
Ruby
Stars
897
Forks
140
PR merge metrics
No merged PRs in 30d

Description

## Describe the bug

👋 Hey guys, I've been playing around dry-types and found an error raised from _sum types_ unexpected.

## To Reproduce

```rb
require 'dry-types' # => 1.5.1
require 'dry-struct' # => 1.4.0
require 'dry/logic' # => 1.2.0
require 'BigDecimal'

module Types
include Dry.Types()
include Dry::Logic
end

class FixedAmount < Dry::Struct
attribute :type, Types.Value("fixed")
attribute :value, Types::Coercible::Decimal.constrained(gteq: BigDecimal(0))
end

class Percentage < Dry::Struct
attribute :type, Types.Value("percentage")
attribute :value, Types::Coercible::Decimal.constrained(gteq: BigDecimal(0), lteq: BigDecimal(100))
end

Value = FixedAmount | Percentage

class DiscountSchema < Dry::Struct
attribute :value, Value
end

# Success
p DiscountSchema.new(value: { type: "fixed", value: "1.1" })
# => #>
p DiscountSchema.new(value: { type: "fixed", value: "1.1", applies_to_each_item: true })
# =>
p DiscountSchema.new(value: { type: "percentage", value: "10" })
# => #>

# Unexpected
p DiscountSchema.new(value: { type: "fixed", value: -1.1 })
# => [Percentage.new] "fixed" (String) has invalid type for :type violates constraints (eql?("percentage", "fixed") failed) (Dry::Struct::Error)
```

## Expected behavior

I'm expecting the error raised for `FixedAmount`, which satisfies the type checking on `:type` but fails the constraint on `:value`. I guess the _sum_ type would try applying both constructors and return last failure as the error.

## My environment

- Affects my production application: NO
- Ruby version: 2.6.8p205
- OS: macOS 12.3

Contributor guide

Open the contributing guide

Research direction

Start with the sum-type handling described in the reproduction and trace how each alternative is constructed and how failures are selected. Reproduce the negative FixedAmount value case, then verify that the resulting error reports the FixedAmount constraint failure rather than the Percentage type failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.