feat(known-error): support multiple regex patterns per known error#325
Merged
Conversation
3051afe to
3131221
Compare
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`spec.pattern` now accepts either a single string (as before) or a list of strings. A log line matching any one of the patterns triggers the known error. Existing single-string configs are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds `minItems: 1` to the list variant of `KnownErrorPattern` via a `schema_with` helper, so schema-aware tooling (IDE validators, CI schema checks) rejects `pattern: []` at authoring time rather than at runtime. The `schema_with` approach is used instead of `#[schemars(length(min=1))]` to keep the published schema clean — the `length` attribute unconditionally emits both `minItems` and a stray `minLength` on array schemas. The runtime empty-list guard in `TryFrom` is kept as defense-in-depth since `validate_resource` only warns on schema mismatches rather than hard-failing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the parallel `patterns: Vec<String>` and `regexes: Vec<Regex>` fields with a single `regex_set: RegexSet`. This resolves two findings from code review in one change: - Eliminates redundant dual storage: `RegexSet::patterns()` returns the original strings in input order, removing the need to store them separately. A `KnownError::patterns()` accessor wraps this for callers. - Improves hot-path efficiency: the match site in `analyze/mod.rs` now calls `regex_set.is_match(&line)`, which runs a single DFA pass over all patterns rather than iterating a `Vec<Regex>` with `.any()`. The explicit empty-list guard in `TryFrom` is kept because `RegexSet::new` succeeds on an empty iterator (returning a set that never matches), so the guard is still needed to surface the configuration error clearly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3131221 to
b1223fe
Compare
ivy
approved these changes
Jun 3, 2026
Member
ivy
left a comment
There was a problem hiding this comment.
Nice job on the backwards compatibility!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
spec.patternnow accepts either a single string (existing behavior, unchanged) or a list of stringsRegexSetfor single-pass matchingDetails
Uses a
#[serde(untagged)]enum (KnownErrorPattern) to accept both forms under the samepatternkey — the same idiom already used bySkipSpecin this codebase. Single-string configs round-trip unchanged; no migration needed.Implementation notes
Manyvariant carriesminItems: 1via aschema_withhelper, so schema-aware tooling (IDE validators, YAML linters) catchespattern: []at authoring time. A runtime guard inTryFromremains as defense-in-depth sincevalidate_resourceonly warns on schema mismatches.patterns: Vec<String>/regexes: Vec<Regex>fields are replaced by a singleregexes: RegexSet.RegexSetmatches all patterns in one DFA pass and exposes the original strings via.patterns(), eliminating the dual-storage issue.useless_vec→ array literal in a test) that would otherwise fail CI under-D warnings.Test plan
cargo test— all existing tests pass (backward compatibility)parses_list_of_patterns,empty_pattern_list_is_rejected,try_from_multi_pattern_specschema_rejects_empty_pattern_list— confirmspattern: []is caught at the schema layercargo test create_and_validate_schemas— regenerated schemas validated against both single-string and multi-pattern example fixturescargo clippy --all-targets --all-features -- -D warnings— clean🤖 Generated with Claude Code