diff --git a/spec/std/xml/reader_spec.cr b/spec/std/xml/reader_spec.cr index d89593620970..c08a664e24e1 100644 --- a/spec/std/xml/reader_spec.cr +++ b/spec/std/xml/reader_spec.cr @@ -581,11 +581,22 @@ module XML it "adds errors to `XML::Error.errors` (deprecated)" do XML::Error.errors # clear class error list - reader = XML::Reader.new(%()) - reader.read - reader.expand? + XML::Reader.new(%()).tap(&.read).expand? + XML::Error.errors.try(&.map(&.to_s)).should eq [ + "Opening and ending tag mismatch: people line 1 and foo", + ] + + %w[foo bar baz qux quux corge grault].each do |tag| + XML::Reader.new(%(<#{tag}>)).tap(&.read).expand? + end - XML::Error.errors.try(&.map(&.to_s)).should eq ["Opening and ending tag mismatch: people line 1 and foo"] + XML::Error.errors.try(&.map(&.to_s)).should eq [ + "Opening and ending tag mismatch: baz line 1 and a", + "Opening and ending tag mismatch: qux line 1 and a", + "Opening and ending tag mismatch: quux line 1 and a", + "Opening and ending tag mismatch: corge line 1 and a", + "Opening and ending tag mismatch: grault line 1 and a", + ] end end end diff --git a/src/xml/error.cr b/src/xml/error.cr index 868dfeb4bd00..e8a07cdecbae 100644 --- a/src/xml/error.cr +++ b/src/xml/error.cr @@ -11,11 +11,28 @@ class XML::Error < Exception super(message) end - @@errors = [] of self + @@max_error_capacity = 5 + + @[Deprecated("This class property is deprecated. XML errors are accessible directly in the respective context via `XML::Reader#errors` and `XML::Node#errors`.")] + def self.max_error_capacity=(@@max_error_capacity) + end + + @[Deprecated("This class property is deprecated. XML errors are accessible directly in the respective context via `XML::Reader#errors` and `XML::Node#errors`.")] + def self.max_error_capacity + @@max_error_capacity + end + + @@errors = Deque(self).new(max_error_capacity) # :nodoc: protected def self.add_errors(errors) - @@errors.concat(errors) + new_errors_size = errors.size.clamp(..max_error_capacity) + remaining_size = max_error_capacity - new_errors_size + (@@errors.size - remaining_size).times { @@errors.shift } + + errors.to_unsafe.to_slice(errors.size)[-new_errors_size, new_errors_size].each do |error| + @@errors.push error + end end @[Deprecated("This class accessor is deprecated. XML errors are accessible directly in the respective context via `XML::Reader#errors` and `XML::Node#errors`.")] @@ -23,7 +40,7 @@ class XML::Error < Exception if @@errors.empty? nil else - errors = @@errors.dup + errors = @@errors.to_a @@errors.clear errors end