Skip to content

Commit eadbc01

Browse files
hakanensariclaude
andcommitted
refactor: standardize error message formatting
Makes all error messages lowercase and adds attribute context to type errors for consistency with Ruby conventions and improved debugging. Changes: - Lowercase error messages: "cannot specify..." instead of "Cannot specify..." - Add attribute name to type errors: "cannot specify X as type for :attr" - Catch and re-raise ArgumentError in Builder#coercions to add context - Update tests to match new error message format Closes #16 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d283f65 commit eadbc01

5 files changed

Lines changed: 17 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2121
User.parse(id: "123") # ✓ valid (name is optional)
2222
```
2323

24+
### Changed
25+
26+
- Standardize error messages to use lowercase for consistency with Ruby conventions
27+
- Improve type error messages to include attribute name for easier debugging
28+
2429
## [4.1.0] - 2025-10-09
2530

2631
### Added

lib/structure/builder.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def attribute(name, type = nil, from: nil, default: nil, null: true, &block)
4646
@non_nullable.add(name) unless null
4747

4848
if type && block
49-
raise ArgumentError, "Cannot specify both type and block for :#{name}"
49+
raise ArgumentError, "cannot specify both type and block for :#{name}"
5050
else
5151
types[name] = type || block
5252
end
@@ -102,7 +102,12 @@ def non_nullable = @non_nullable.to_a
102102

103103
# @api private
104104
def coercions(context = nil)
105-
@types.transform_values { |type| Types.coerce(type, context) }
105+
@types.to_h do |attr, type|
106+
coercion = Types.coerce(type, context)
107+
[attr, coercion]
108+
rescue ArgumentError => e
109+
raise ArgumentError, "#{e.message} for :#{attr}"
110+
end
106111
end
107112

108113
# @api private

lib/structure/types.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def coerce(type, context = nil)
6060
when String
6161
lazy_class(type, context)
6262
else
63-
raise ArgumentError, "Cannot specify #{type.inspect} as type"
63+
raise ArgumentError, "cannot specify #{type.inspect} as type"
6464
end
6565
end
6666

test/test_core_structure.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def test_attribute_with_both_type_and_block_raises_error
8585
end
8686
end
8787

88-
assert_match(/Cannot specify both type and block/, error.message)
88+
assert_match(/cannot specify both type and block/, error.message)
8989
end
9090

9191
def test_attribute_with_default_value

test/test_type_coercions.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,12 @@ def test_empty_hash_type_raises_error
152152
def test_invalid_object_type_raises_error
153153
invalid_object = Object.new
154154

155-
assert_raises(ArgumentError) do
155+
error = assert_raises(ArgumentError) do
156156
Structure.new do
157157
attribute(:value, invalid_object)
158158
end
159159
end
160+
161+
assert_match(/cannot specify.*as type for :value/, error.message)
160162
end
161163
end

0 commit comments

Comments
 (0)