Skip to content

Commit

Permalink
Keep all errors for all union types and attach the schema name
Browse files Browse the repository at this point in the history
..So not only the errors from the first failed union type are kept
  • Loading branch information
davidgm0 committed Jan 23, 2023
1 parent fc2a4e0 commit 34861b0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
20 changes: 15 additions & 5 deletions lang/ruby/lib/avro/schema_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,14 @@ def validate_union(expected_schema, datum, path, result, options)
compatible_type = first_compatible_type(datum, expected_schema, path, failures, options)
return unless compatible_type.nil?

complex_type_failed = failures.detect { |r| COMPLEX_TYPES.include?(r[:type]) }
if complex_type_failed
complex_type_failed[:result].errors.each { |error| result << error }
complex_type_failed = failures.select { |r| COMPLEX_TYPES.include?(r[:type]) }
if complex_type_failed.any?
complex_type_failed.each do |type_failures|
type_failures[:result].errors.each do |error|
error_msg = type_failures[:schema] ? "#{type_failures[:schema]} #{error}" : error
result << error_msg
end
end
else
types = expected_schema.schemas.map { |s| "'#{s.type_sym}'" }.join(', ')
result.add_error(path, "expected union of [#{types}], got #{actual_value_message(datum)}")
Expand All @@ -208,11 +213,16 @@ def validate_union(expected_schema, datum, path, result, options)
def first_compatible_type(datum, expected_schema, path, failures, options = {})
expected_schema.schemas.find do |schema|
# Avoid expensive validation if we're just validating a nil
next datum.nil? if schema.type_sym == :null
if schema.type_sym == :null
next datum.nil?
end

result = Result.new
validate_recursive(schema, datum, path, result, options)
failures << { type: schema.type_sym, result: result } if result.failure?

failure = { type: schema.type_sym, result: result }
failure[:schema] = schema.name if schema.is_a?(Avro::Schema::RecordSchema)
failures << failure if result.failure?
!result.failure?
end
end
Expand Down
2 changes: 1 addition & 1 deletion lang/ruby/test/test_schema_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ def test_validate_union_extra_fields
validate!(schema, { 'name' => 'apple', 'color' => 'green' }, fail_on_extra_fields: true)
end
assert_equal(1, exception.result.errors.size)
assert_equal("at . extra field 'color' - not in schema", exception.to_s)
assert_equal("fruit at . extra field 'color' - not in schema", exception.to_s)
end

def test_validate_bytes_decimal
Expand Down

0 comments on commit 34861b0

Please sign in to comment.