Skip to content

fix(proxy): tighten numeric error status boundaries#1104

Merged
ding113 merged 6 commits into
devfrom
fix/error-rule-regex-boundaries-20260425
Apr 25, 2026
Merged

fix(proxy): tighten numeric error status boundaries#1104
ding113 merged 6 commits into
devfrom
fix/error-rule-regex-boundaries-20260425

Conversation

@ding113
Copy link
Copy Markdown
Owner

@ding113 ding113 commented Apr 25, 2026

Summary

Tighten the built-in ERROR_STATUS_MATCHERS regexes and guard the default error-rule catalog against false-positive numeric substring matches. Numeric HTTP status tokens (e.g. 503) and Cloudflare Error codes (e.g. 521, 524) previously matched inside longer digit sequences such as AWS request IDs (...05503999959...) or decimal prices (0.352942), causing incorrect upstream-error-status inference.

Related:

Problem

When an upstream returns a fake-200 response body containing a request ID or price, the numeric HTTP status regexes in ERROR_STATUS_MATCHERS could match a numeric substring and infer the wrong error status code. For example:

  • request id: 202604250550399959 contains 503 at positions 13-15, causing service_unavailable inference
  • 需要预扣费额度:¥0.352942 contains 529 inside the decimal price, potentially triggering rate-limit inference

The root cause was that the status-code alternations used only \b word boundaries, which allow a match when the digits are followed by more digits or a decimal point (e.g. 503.12, 521.7).

Solution

Replace bare \b word-boundary assertions on numeric status tokens with negative lookaheads (?\!\d|\.\d) that reject matches followed by additional digits or decimal fractions. Apply the same boundary tightening to Cloudflare Error codes (1015, 1020, 521, 522, 524). For the 429 HTTP status alternation, also add a negative lookbehind (?<\![\d.]) to prevent matching when preceded by digits or a decimal point (e.g. inside a price).

Changes

Core Changes

  • src/lib/utils/upstream-error-detection.ts (+15/-15) - Replace \b boundaries with (?\!\d|\.\d) on all 15 HTTP status code alternations and 5 Cloudflare Error code alternations; add (?<\![\d.]) lookbehind on the 429 standalone status alternation

Test Coverage

  • tests/unit/lib/upstream-error-detection-status.test.ts (new, 95 lines) - 63 test cases covering: standalone HTTP status matches (still work), decimal-suffix rejection (503.12), longer-number rejection (50312), Cloudflare Error standalone matches, Cloudflare decimal/longer-number rejection, and regression tests for the reported request-id and price samples
  • tests/unit/repository/error-rules-default-numeric-boundaries.test.ts (new, 122 lines) - Validates that all default regex error rules loaded by syncDefaultErrorRules() do not accidentally match the reported request-id and price samples

Verification

  • bunx vitest run tests/unit/lib/upstream-error-detection-status.test.ts tests/unit/repository/error-rules-default-numeric-boundaries.test.ts -> 2 files / 63 tests passed
  • bun run lint:fix -> exit 0; fixed formatting only
  • bun run lint -> exit 0; 3 existing info-level suggestions in unrelated leaderboard tests
  • bun run typecheck -> exit 0
  • bun run build -> exit 0
  • bunx vitest run tests/unit/public-status/config-publisher.test.ts -> exit 0 after investigating the full-suite timeout
  • VITEST_MAX_WORKERS=4 bun run test -> 547 files / 5136 tests passed, 13 skipped

Notes

  • Plain bun run test hit an unrelated 20s timeout in tests/unit/public-status/config-publisher.test.ts; the same test passes alone in ~15s and the full suite passes with reduced workers, matching the repo's configurable worker guidance.
  • No breaking changes. The tightened boundaries only reject previously-incorrect matches; all legitimate standalone status/code tokens continue to match.

Description enhanced by Claude AI

Greptile Summary

This PR tightens the numeric boundary guards in ERROR_STATUS_MATCHERS by replacing trailing \b word-boundary assertions with (?![\p{L}\p{N}_]|\.\d) negative lookaheads on all 15 HTTP status alternations and 5 Cloudflare Error code alternations, and adds a (?<![\p{L}\p{N}_.]) lookbehind on the standalone 429 alternative. Two new test files provide 63 parametrised unit tests for the regex changes and a mock-based integration check against the default DB rules.

Confidence Score: 5/5

Safe to merge — the regex changes are mechanically uniform, fully backward-compatible, and backed by comprehensive parametrised tests.

No P0 or P1 findings. The single P2 (missing u flag in test helper) is latent and harmless while DB rules remain free of Unicode property escapes. Core logic in the production file is correct.

tests/unit/repository/error-rules-default-numeric-boundaries.test.ts — the matchesRule helper uses new RegExp(pattern, "i") without u; benign today but could mask failures if DB rules adopt \p{…} patterns in the future.

Important Files Changed

Filename Overview
src/lib/utils/upstream-error-detection.ts Replaces trailing \b with `(?![\p{L}\p{N}_]
tests/unit/lib/upstream-error-detection-status.test.ts New test file with 63 parametrised cases covering standalone match, decimal-suffix rejection, longer-number rejection, letter-suffix rejection, punctuation passthrough for both HTTP statuses and Cloudflare codes, plus two regression samples. Coverage is thorough and correct.
tests/unit/repository/error-rules-default-numeric-boundaries.test.ts New test that intercepts syncDefaultErrorRules() via mocks and asserts no default rule matches the two reported false-positive samples. Minor: matchesRule compiles regexes with only the "i" flag, missing "u", which would cause a SyntaxError if any future DB rule uses Unicode property escapes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Upstream fake-200 response body text"] --> B["inferUpstreamErrorStatusCodeFromText()"]
    B --> C["Trim + BOM strip + truncate to 64 KB"]
    C --> D["Iterate ERROR_STATUS_MATCHERS"]
    D --> E{"matcher.re.test(text)"}
    E -- "match" --> F["Return { statusCode, matcherId }"]
    E -- "no match" --> G{"More matchers?"}
    G -- "yes" --> D
    G -- "no" --> H["Return null"]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: tests/unit/repository/error-rules-default-numeric-boundaries.test.ts
Line: 113

Comment:
**Missing `u` flag in test regex compilation**

`matchesRule` constructs regexes with only `"i"` but the production matchers use `"iu"`. If any future default rule stores a pattern with a Unicode property escape (`\p{L}`, `\p{N}`, etc.), this line would throw a `SyntaxError` rather than failing a normal assertion, making the test failure misleading. Using `"iu"` here keeps the test semantics consistent with how the rules are applied in production.

```suggestion
  return new RegExp(rule.pattern, "iu").test(sample);
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (4): Last reviewed commit: "fix(proxy): allow punctuation after nume..." | Re-trigger Greptile

ding113 and others added 2 commits April 25, 2026 10:49
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

📝 Walkthrough

Walkthrough

更新上游错误检测正则以改进数值边界判定,并新增两套单元测试以验证状态码/错误码识别与默认规则的数值边界不会产生意外命中。

Changes

Cohort / File(s) Summary
上游错误检测正则表达式更新
src/lib/utils/upstream-error-detection.ts
调整 ERROR_STATUS_MATCHERS 中的正则:对 HTTP/<ver> <status> 替代分支引入 Unicode 感知的负前瞻/负后顾以收紧数值令牌识别;对 429 分支增加额外边界断言以避免与相邻字母/数字/下划线或点分数字形式连在一起时误匹配(约 +15/-15 行)。
上游错误检测测试套件
tests/unit/lib/upstream-error-detection-status.test.ts
新增参数化单元测试 inferUpstreamErrorStatusCodeFromText:验证多种 HTTP 状态码与 Cloudflare Error <code> 在独立令牌与边界情形(小数后缀、嵌入更长数字、字母后缀、句末标点)下的匹配/不匹配行为(+130 行)。
默认错误规则数值边界测试
tests/unit/repository/error-rules-default-numeric-boundaries.test.ts
新增 syncDefaultErrorRules 单元测试:通过模拟 Drizzle 事务捕获插入的默认规则并校验这些规则不会对包含数字的示例字符串产生意外匹配(+131 行)。

Estimated code review effort

🎯 3 (中等) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确总结了主要变更:通过增强正则表达式边界来修复数字HTTP状态码的误匹配问题。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR描述详细阐述了问题根源、解决方案、核心改动、测试覆盖和验证步骤,与代码改动完全相关。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/error-rule-regex-boundaries-20260425

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added bug Something isn't working area:Error Rule area:provider size/M Medium PR (< 500 lines) labels Apr 25, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refines the regex patterns used for upstream error detection to prevent false positives when status codes appear as substrings in larger numbers, such as request IDs or prices. It also introduces unit tests to verify these numeric boundary conditions. Feedback suggests refining the regex patterns further by combining word boundaries with negative lookaheads to maintain strictness (e.g., preventing matches like '429abc'). Additionally, it is recommended to expand the new boundary tests to include 'contains' and 'exact' match types in addition to 'regex'.

statusCode: 429,
matcherId: "rate_limit",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b|\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b|超出频率|请求过于频繁|限流|稍后重试)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\d|\.\d)|超出频率|请求过于频繁|限流|稍后重试)/iu,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The replacement of \b with (?!\d|\.\d) is slightly less strict than the original word boundary because it allows word characters like letters or underscores (e.g., 429abc would now match).

To achieve the goal of excluding decimal suffixes while maintaining the word boundary check, you can use \b(?!\.\d). This ensures that the match ends at a word boundary, but specifically fails if that boundary is a dot followed by a digit (a decimal).

Additionally, for the standalone 429 match, using (?<![\d.]) without \b allows matches preceded by letters (e.g., a429). Combining them as (?<![\d.])\b is safer. This logic applies to all other matchers in this array as well.

Suggested change
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\d|\.\d)||||)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b(?!\.\d)|(?<![\d.])\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b(?!\.\d)||||)/iu,

Comment on lines +110 to +118
const regexRules = (await loadDefaultRules()).filter((rule) => rule.matchType === "regex");
const samples = ["request id: 202604250550399959", "需要预扣费额度:¥0.352942"];

const accidentalMatches = regexRules.flatMap((rule) => {
const pattern = new RegExp(rule.pattern, "i");
return samples
.filter((sample) => pattern.test(sample))
.map((sample) => ({ category: rule.category, pattern: rule.pattern, sample }));
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current test only validates regex match types. It would be more robust to also check contains and exact rules, as a simple contains: "503" rule would also cause the false positive issue with request IDs or prices.

    const allRules = await loadDefaultRules();
    const samples = ["request id: 202604250550399959", "需要预扣费额度:¥0.352942"];

    const accidentalMatches = allRules.flatMap((rule) => {
      return samples
        .filter((sample) => {
          if (rule.matchType === "regex") {
            return new RegExp(rule.pattern, "i").test(sample);
          }
          if (rule.matchType === "contains") {
            return sample.toLowerCase().includes(rule.pattern.toLowerCase());
          }
          if (rule.matchType === "exact") {
            return sample.toLowerCase() === rule.pattern.toLowerCase();
          }
          return false;
        })
        .map((sample) => ({ category: rule.category, pattern: rule.pattern, sample }));
    });

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb490c6c1d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

statusCode: 429,
matcherId: "rate_limit",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b|\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b|超出频率|请求过于频繁|限流|稍后重试)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\d|\.\d)|超出频率|请求过于频繁|限流|稍后重试)/iu,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore strict token boundary after numeric status codes

Replacing the trailing \b with (?!\d|\.\d) makes these matchers accept alphabetic suffixes, so malformed tokens like HTTP/1.1 429abc or Error 1015x now infer an upstream status instead of being ignored. This is a regression from the previous boundary behavior and can skew fake-200 status inference used for failover/circuit-breaker accounting. Keep the decimal/long-number guard, but also require a non-word boundary after the numeric token (e.g., \b or (?![\w.])).

Useful? React with 👍 / 👎.

@github-actions
Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Comment on lines +90 to +94
it("does not infer overloaded status from a decimal price containing 529", () => {
const text = "需要预扣费额度:¥0.352942";

expect(inferUpstreamErrorStatusCodeFromText(text)).toBeNull();
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test title references a non-existent status code

The test description says "overloaded status from a decimal price containing 529", but 529 is not a code covered by any entry in ERROR_STATUS_MATCHERS, so the inline explanation is misleading for future maintainers. The test correctly returns null today because no pattern targets 529, but the comment implies an existing risk that doesn't exist yet — the real protection being exercised here is against patterns in the database-stored default rules (covered by the second test file). Rewording to "does not infer any error status from a decimal price whose digits contain a known error-code substring" would be more accurate.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/unit/lib/upstream-error-detection-status.test.ts
Line: 90-94

Comment:
**Test title references a non-existent status code**

The test description says "overloaded status from a decimal price containing 529", but `529` is not a code covered by any entry in `ERROR_STATUS_MATCHERS`, so the inline explanation is misleading for future maintainers. The test correctly returns `null` today because no pattern targets `529`, but the comment implies an existing risk that doesn't exist yet — the real protection being exercised here is against patterns in the *database-stored* default rules (covered by the second test file). Rewording to "does not infer any error status from a decimal price whose digits contain a known error-code substring" would be more accurate.

How can I resolve this? If you propose a fix, please make it concise.

statusCode: 429,
matcherId: "rate_limit",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b|\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b|超出频率|请求过于频繁|限流|稍后重试)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\d|\.\d)|超出频率|请求过于频繁|限流|稍后重试)/iu,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Asymmetric left-boundary guard for the standalone 429 alternative

The 429 regex is the only matcher that adds a left-side lookbehind ((?<![\d.])) on the standalone status-number alternative, while all other status codes rely solely on the \bHTTP\/\d… prefix (which implicitly anchors the left side). The 429 too many requests phrase is indeed unique in that it can appear without the HTTP prefix, but \b429 would already prevent matching when the preceding character is a digit. The additional (?<![\d.]) guard is stricter: it also blocks a preceding literal ., which \b would allow (e.g., $0.429 too many requests).

This is likely intentional and correct, but it's the only case with this extra guard and worth a brief inline comment explaining why, so the asymmetry doesn't look like an oversight to future editors.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/utils/upstream-error-detection.ts
Line: 98

Comment:
**Asymmetric left-boundary guard for the standalone `429` alternative**

The 429 regex is the only matcher that adds a left-side lookbehind (`(?<![\d.])`) on the standalone status-number alternative, while all other status codes rely solely on the `\bHTTP\/\d…` prefix (which implicitly anchors the left side). The `429 too many requests` phrase is indeed unique in that it can appear without the HTTP prefix, but `\b429` would already prevent matching when the preceding character is a digit. The additional `(?<![\d.])` guard is stricter: it also blocks a preceding literal `.`, which `\b` would allow (e.g., `$0.429 too many requests`).

This is likely intentional and correct, but it's the only case with this extra guard and worth a brief inline comment explaining why, so the asymmetry doesn't look like an oversight to future editors.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +147 to +148
matcherId: "legal_restriction",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+451\b|\bunavailable\s+for\s+legal\s+reasons\b|\bexport\s+control\b|\bsanctions?\b|法律原因不可用|合规限制|出口管制)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+451(?!\d|\.\d)|\bunavailable\s+for\s+legal\s+reasons\b|\bexport\s+control\b|\bsanctions?\b|法律原因不可用|合规限制|出口管制)/iu,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 (?!\d|\.\d) does not guard against a trailing bare period

The negative lookahead (?!\d|\.\d) prevents 451.7 (. + digit) from matching, but HTTP/1.1 451. (period followed by a non-digit, e.g. end-of-sentence) would still match. The same applies to every matcher in the array. In practice the sentence-ending period case ("...received 451.") is harmless and the old \b had the same behaviour, so this is not a regression — just worth noting that the fix is specifically scoped to decimal-fraction false positives, not bare trailing dots.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/utils/upstream-error-detection.ts
Line: 147-148

Comment:
**`(?!\d|\.\d)` does not guard against a trailing bare period**

The negative lookahead `(?!\d|\.\d)` prevents `451.7` (`.` + digit) from matching, but `HTTP/1.1 451.` (period followed by a non-digit, e.g. end-of-sentence) would still match. The same applies to every matcher in the array. In practice the sentence-ending period case (`"...received 451."`) is harmless and the old `\b` had the same behaviour, so this is not a regression — just worth noting that the fix is specifically scoped to decimal-fraction false positives, not bare trailing dots.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
tests/unit/repository/error-rules-default-numeric-boundaries.test.ts (2)

6-10: CapturedDefaultRule 类型相对实际写入字段偏窄,建议明确收窄意图或补全字段。

syncDefaultErrorRulestx.insert(errorRules).values(rule) 时会传入完整 rule(priorityoverrideResponseisEnabledisDefault 等),但这里的捕获类型只声明了 pattern / matchType / category 三个字段,运行时虽然不会出问题,但读起来像是在断言"只传这三个字段"。

如果意图就是"本测试只关心这三字段",可以在类型注释里点一句;如果担心未来字段被误改,可补完类型让 TS 在 tx.insert(...).values(rule) 形态变化时给出反馈。当前写法可接受,仅作 nit。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts` around
lines 6 - 10, CapturedDefaultRule is too narrow compared to the actual object
passed into syncDefaultErrorRules (tx.insert(errorRules).values(rule))—either
document that the test intentionally only asserts pattern/matchType/category or
expand CapturedDefaultRule to include the other real fields (e.g., priority,
overrideResponse, isEnabled, isDefault) so TypeScript will catch future shape
changes; update the type declaration for CapturedDefaultRule (or add an inline
comment above it) and ensure it matches the shape used by
tx.insert(...).values(rule).

113-118: 可选优化:在 flatMap 外层一次性编译 RegExp。

new RegExp(rule.pattern, "i") 在 flatMap 内每条规则重新构造,对当前样本量级(默认规则数 × 2 个样本)无可见性能影响,但可读性上把"编译"和"测试"分开会更清晰;同时也方便后续把样本扩展到更多场景:

♻️ 可选 refactor
-    const accidentalMatches = regexRules.flatMap((rule) => {
-      const pattern = new RegExp(rule.pattern, "i");
-      return samples
-        .filter((sample) => pattern.test(sample))
-        .map((sample) => ({ category: rule.category, pattern: rule.pattern, sample }));
-    });
+    const compiled = regexRules.map((rule) => ({ ...rule, regex: new RegExp(rule.pattern, "i") }));
+    const accidentalMatches = compiled.flatMap((rule) =>
+      samples
+        .filter((sample) => rule.regex.test(sample))
+        .map((sample) => ({ category: rule.category, pattern: rule.pattern, sample })),
+    );

注:静态分析对该行报了 ReDoS(CWE-1333)。这里 rule.pattern 来源于仓库内置的 DEFAULT_ERROR_RULES,不是外部输入,且仅在单测里编译,不构成真实的 ReDoS 风险,可以忽略该告警。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts` around
lines 113 - 118, The code repeatedly constructs RegExp inside the flatMap for
each rule; extract compilation by mapping regexRules to a new array of objects
like { category, pattern, regex: new RegExp(pattern, "i") } (referencing
regexRules, accidentalMatches, samples and pattern) and then use that compiled
regex in the flatMap/test loop so RegExp instantiation happens once per rule and
the testing step is separated from compilation.
src/lib/utils/upstream-error-detection.ts (2)

98-98: 429 分支的边界改写存在一处副作用,建议确认是否符合预期。

第二分支由(推测原状)\b429\s+too\s+many\s+requests\b 改为 (?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b 后:

  • .429 too many requests 这类小数前缀场景比 \b 更严格(符合 PR 目标);
  • 但对 user429 too many requests 这类字母直接相连的场景反而比 \b 更宽松(\b 在两个 word 字符之间不成立而拒绝匹配;(?<![\d.]) 因为前一字符是字母而通过)。

实际上游错误文本里 字母+429+空格+too many requests 的概率应该极低,且本分支仍然要求 too many requests 关键词共现,误判风险有限。如果你希望同时覆盖这两类场景,可以把锚定改为 (?<![\w.])429(?!\d|\.\d),让数字、点号、字母三类前缀都被排除:

🛡️ 可选加固(同时排除字母前缀)
-    re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|...
+    re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\w.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|...
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/upstream-error-detection.ts` at line 98, The 429-branch regex
in upstream-error-detection.ts tightened the left boundary from \b to (?<![\d.])
which still allows letter-prefixed matches (e.g., "user429 too many requests");
update that lookbehind to also exclude word characters by using (?<![\w.]) for
the specific subpattern that currently reads
(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b so it rejects prefixes of
digits, dots, or letters while preserving the intended stricter numeric/dot
exclusion behavior.

94-170: 数字边界收紧实现正确,逻辑符合预期。

(?!\d|\.\d) 在所有 HTTP/<version> <status>Error <code> 分支上有效阻止了 503.12 / 52312 之类的延伸匹配;429 分支额外加了 (?<![\d.])429 来防止小数前缀(如 .429)误命中,方向正确。

可选的小重构:(?!\d|\.\d) 在语义上等价于更紧凑的 (?!\.?\d),每条规则可少一个分支节点,可读性也略好;如果倾向于显式分写两种情况,保持现状也完全可以。例如对 429 行:

♻️ 可选简化(保留行为不变)
-    re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\d|\.\d)|(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\d|\.\d)|超出频率|请求过于频繁|限流|稍后重试)/iu,
+    re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?!\.?\d)|(?<![\d.])429(?!\.?\d)\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?!\.?\d)|超出频率|请求过于频繁|限流|稍后重试)/iu,

其余 14 条规则同理可统一替换。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/upstream-error-detection.ts` around lines 94 - 170, The
negative lookahead (?!\d|\.\d) used in the HTTP/<version> <status> and Error
<code> branches can be simplified to the equivalent, more compact pattern
(?!\.?\d) for improved readability; update the RegExp literals inside
ERROR_STATUS_MATCHERS (e.g., entries with matcherId "rate_limit",
"payment_required", "unauthorized", "forbidden", "not_found",
"payload_too_large", "unsupported_media_type", "conflict",
"unprocessable_entity", "request_timeout", "legal_restriction",
"service_unavailable", "gateway_timeout", "internal_server_error",
"bad_request") by replacing occurrences of (?!\d|\.\d) with (?!\.?\d) so
behavior remains identical but regexes are slightly simpler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts`:
- Around line 109-121: The test "default regex rules do not match numeric
substrings in request ids or prices" currently only asserts accidentalMatches is
empty which can yield a false positive if no regex rules were loaded; after
computing regexRules (from loadDefaultRules()) add an assertion that
regexRules.length is greater than 0 (e.g.,
expect(regexRules.length).toBeGreaterThan(0)) to ensure at least one regex rule
from DEFAULT_ERROR_RULES was compiled and actually exercised before checking
accidentalMatches.

---

Nitpick comments:
In `@src/lib/utils/upstream-error-detection.ts`:
- Line 98: The 429-branch regex in upstream-error-detection.ts tightened the
left boundary from \b to (?<![\d.]) which still allows letter-prefixed matches
(e.g., "user429 too many requests"); update that lookbehind to also exclude word
characters by using (?<![\w.]) for the specific subpattern that currently reads
(?<![\d.])429(?!\d|\.\d)\s+too\s+many\s+requests\b so it rejects prefixes of
digits, dots, or letters while preserving the intended stricter numeric/dot
exclusion behavior.
- Around line 94-170: The negative lookahead (?!\d|\.\d) used in the
HTTP/<version> <status> and Error <code> branches can be simplified to the
equivalent, more compact pattern (?!\.?\d) for improved readability; update the
RegExp literals inside ERROR_STATUS_MATCHERS (e.g., entries with matcherId
"rate_limit", "payment_required", "unauthorized", "forbidden", "not_found",
"payload_too_large", "unsupported_media_type", "conflict",
"unprocessable_entity", "request_timeout", "legal_restriction",
"service_unavailable", "gateway_timeout", "internal_server_error",
"bad_request") by replacing occurrences of (?!\d|\.\d) with (?!\.?\d) so
behavior remains identical but regexes are slightly simpler.

In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts`:
- Around line 6-10: CapturedDefaultRule is too narrow compared to the actual
object passed into syncDefaultErrorRules
(tx.insert(errorRules).values(rule))—either document that the test intentionally
only asserts pattern/matchType/category or expand CapturedDefaultRule to include
the other real fields (e.g., priority, overrideResponse, isEnabled, isDefault)
so TypeScript will catch future shape changes; update the type declaration for
CapturedDefaultRule (or add an inline comment above it) and ensure it matches
the shape used by tx.insert(...).values(rule).
- Around line 113-118: The code repeatedly constructs RegExp inside the flatMap
for each rule; extract compilation by mapping regexRules to a new array of
objects like { category, pattern, regex: new RegExp(pattern, "i") } (referencing
regexRules, accidentalMatches, samples and pattern) and then use that compiled
regex in the flatMap/test loop so RegExp instantiation happens once per rule and
the testing step is separated from compilation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd59a1d6-f599-409c-b44b-c3acbfd8284d

📥 Commits

Reviewing files that changed from the base of the PR and between 4ec2d17 and fb490c6.

📒 Files selected for processing (3)
  • src/lib/utils/upstream-error-detection.ts
  • tests/unit/lib/upstream-error-detection-status.test.ts
  • tests/unit/repository/error-rules-default-numeric-boundaries.test.ts

Comment thread tests/unit/repository/error-rules-default-numeric-boundaries.test.ts Outdated
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

No significant issues identified in this PR.

PR Size: M

  • Lines changed: 247
  • Files changed: 3

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Automated review by Codex AI

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed PR #1104 (fix(proxy): tighten numeric error status boundaries).

  • PR Size: M (247 lines changed across 3 files); applied label size/M.
  • Inline comments: none (no diff-line issues met the reporting threshold).
  • Review summary: submitted via gh pr review --comment on PR #1104.

ding113 and others added 2 commits April 25, 2026 11:22
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions
Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd1fb2e479

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

statusCode: 429,
matcherId: "rate_limit",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b|\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b|超出频率|请求过于频繁|限流|稍后重试)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?![\p{L}\p{N}_.])|(?<![\p{L}\p{N}_.])429(?![\p{L}\p{N}_.])\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?![\p{L}\p{N}_.])|超出频率|请求过于频繁|限流|稍后重试)/iu,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Permit sentence punctuation after status tokens

Changing the trailing boundary from \b to (?![\p{L}\p{N}_.]) now rejects status tokens followed by a period, so bodies like "upstream returned HTTP/1.1 503." (or "Error 521.") no longer infer the upstream status and fall back to 502. This is a regression from the previous matcher behavior and can reduce the accuracy of fake-200 failure classification when providers/loggers end sentences with punctuation; the decimal false-positive case can be blocked without dropping bare punctuation matches.

Useful? React with 👍 / 👎.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/unit/repository/error-rules-default-numeric-boundaries.test.ts (1)

119-119: 可选:扩展样本以覆盖更多潜在数字边界场景。

当前只用两个样本(请求 ID 与价格小数)做回归,覆盖了 PR 提到的两类已知问题。若希望对未来 pattern 调整提供更强的护栏,可补充几个临界样本(如纯数字前后紧邻字母/标点、HTTP/1.1v4295031 等),进一步约束 (?!\d|\.\d)(?<![\d.]) 边界的覆盖范围。当前实现不阻塞合并。

♻️ 可选样本扩充
-    const samples = ["request id: 202604250550399959", "需要预扣费额度:¥0.352942"];
+    const samples = [
+      "request id: 202604250550399959",
+      "需要预扣费额度:¥0.352942",
+      "price: 503.12 USD",
+      "version v429 build 5031",
+      "trace=4290abc",
+    ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts` at line
119, 当前 tests/unit/repository/error-rules-default-numeric-boundaries.test.ts 中
samples 数组只包含两个样本,建议在 samples(变量名 samples)中增加更多边界样例以覆盖 `(?!\d|\.\d)` 与
`(?<![\d.])` 这类正则断言的临界场景;具体新增示例可包括纯数字与字母相邻(如 "v429"、"5031")、带小数点的协议/版本(如
"HTTP/1.1")、数字前后紧邻标点或字母(如 "id123abc"、"123,456"、"price:¥0.35")等,以更全面验证 Regex
策略(不阻塞合并,属于可选增强)。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/unit/repository/error-rules-default-numeric-boundaries.test.ts`:
- Line 119: 当前
tests/unit/repository/error-rules-default-numeric-boundaries.test.ts 中 samples
数组只包含两个样本,建议在 samples(变量名 samples)中增加更多边界样例以覆盖 `(?!\d|\.\d)` 与 `(?<![\d.])`
这类正则断言的临界场景;具体新增示例可包括纯数字与字母相邻(如 "v429"、"5031")、带小数点的协议/版本(如
"HTTP/1.1")、数字前后紧邻标点或字母(如 "id123abc"、"123,456"、"price:¥0.35")等,以更全面验证 Regex
策略(不阻塞合并,属于可选增强)。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ff1c1392-27e8-4463-ab59-0c4ea65bbcdd

📥 Commits

Reviewing files that changed from the base of the PR and between dd1fb2e and 0b73501.

📒 Files selected for processing (1)
  • tests/unit/repository/error-rules-default-numeric-boundaries.test.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b73501014

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

statusCode: 429,
matcherId: "rate_limit",
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429\b|\b429\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015\b|超出频率|请求过于频繁|限流|稍后重试)/iu,
re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?![\p{L}\p{N}_.])|(?<![\p{L}\p{N}_.])429(?![\p{L}\p{N}_.])\s+too\s+many\s+requests\b|\btoo\s+many\s+requests\b|\brate\s*limit(?:ed|ing)?\b|\bthrottl(?:e|ed|ing)\b|\bretry-after\b|\bRESOURCE_EXHAUSTED\b|\bRequestLimitExceeded\b|\bThrottling(?:Exception)?\b|\bError\s*1015(?![\p{L}\p{N}_.])|超出频率|请求过于频繁|限流|稍后重试)/iu,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow sentence punctuation after numeric status tokens

The new boundary check (?![\p{L}\p{N}_.]) blocks a trailing . after matched numeric tokens, so inputs like HTTP/1.1 503. and Error 521. now fail status inference even though they are standalone status/code tokens followed by sentence punctuation. In fake-200 handling this falls back to the generic 502 path and reduces classification accuracy for provider messages or logs that end with periods. You can keep the decimal/embedded-number guard while still permitting punctuation-only terminators.

Useful? React with 👍 / 👎.

@github-actions
Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions
Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/lib/utils/upstream-error-detection.ts (1)

94-170: 正则边界收紧实现正确,建议抽取重复的负向先行模式以便集中维护。

负向先行 (?![\p{L}\p{N}_]|\.\d) 与 429 标准独立分支的负向后行 (?<![\p{L}\p{N}_.]) 设计是合理的——前者拒绝紧邻的标记字符或小数后缀(同时允许句尾 .),后者拒绝前置的数字 / 下划线 / 小数点(前置 . 一定是小数上下文)。15 个 HTTP 状态码与 5 个 Cloudflare 错误码全部覆盖,配合 /iu 标志即可使用 \p{L}\p{N} Unicode 字符类。

唯一可优化点:(?![\p{L}\p{N}_]|\.\d) 字面在 20 处出现,若以后需要调整边界语义(如增加对十六进制字符的拒绝、放开下划线等),需要同步修改全部 20 处,存在漏改风险。

♻️ 可选:抽取边界片段为常量,使用 RegExp 构造器拼装
+// 数字 token 后的边界:拒绝紧邻的字母/数字/下划线,以及小数后缀(如 .12);
+// 允许句尾 `.`、空白、标点等正常分隔符。统一在此调整以保持 20 处规则一致。
+const NUMERIC_TOKEN_TAIL_BOUNDARY = "(?![\\p{L}\\p{N}_]|\\.\\d)";
+const NB = NUMERIC_TOKEN_TAIL_BOUNDARY;
+
 const ERROR_STATUS_MATCHERS: Array<{ statusCode: number; matcherId: string; re: RegExp }> = [
   {
     statusCode: 429,
     matcherId: "rate_limit",
-    re: /(?:\bHTTP\/\d(?:\.\d)?\s+429(?![\p{L}\p{N}_]|\.\d)|(?<![\p{L}\p{N}_.])429(?![\p{L}\p{N}_]|\.\d)\s+too\s+many\s+requests\b|...|\bError\s*1015(?![\p{L}\p{N}_]|\.\d)|超出频率|...)/iu,
+    re: new RegExp(
+      `(?:\\bHTTP\\/\\d(?:\\.\\d)?\\s+429${NB}|(?<![\\p{L}\\p{N}_.])429${NB}\\s+too\\s+many\\s+requests\\b|...|\\bError\\s*1015${NB}|超出频率|...)`,
+      "iu",
+    ),
   },
   // ... 其余 14 条同理
 ];

如果不希望引入字符串拼装的可读性成本,保留现状也是可以接受的——这只是降低未来维护误差的预防性建议。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/upstream-error-detection.ts` around lines 94 - 170, The
repeated negative-lookahead boundary fragment "(?![\\p{L}\\p{N}_]|\\.\\d)" used
across ERROR_STATUS_MATCHERS should be extracted to a single constant (e.g.,
NEGATIVE_TRAILING_BOUNDARY) and the regexes should be constructed by composing
that constant (via RegExp constructor or string template assembly) instead of
repeating the literal in each entry; locate the ERROR_STATUS_MATCHERS array and
replace the inline fragment in each object's re with a composed regex built from
the shared constant so future updates to boundary semantics only require one
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/lib/utils/upstream-error-detection.ts`:
- Around line 94-170: The repeated negative-lookahead boundary fragment
"(?![\\p{L}\\p{N}_]|\\.\\d)" used across ERROR_STATUS_MATCHERS should be
extracted to a single constant (e.g., NEGATIVE_TRAILING_BOUNDARY) and the
regexes should be constructed by composing that constant (via RegExp constructor
or string template assembly) instead of repeating the literal in each entry;
locate the ERROR_STATUS_MATCHERS array and replace the inline fragment in each
object's re with a composed regex built from the shared constant so future
updates to boundary semantics only require one change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3acab3d2-f847-4c0e-8d74-69b4027c35cf

📥 Commits

Reviewing files that changed from the base of the PR and between 0b73501 and 14a50c0.

📒 Files selected for processing (2)
  • src/lib/utils/upstream-error-detection.ts
  • tests/unit/lib/upstream-error-detection-status.test.ts

@ding113 ding113 merged commit c6cbb0a into dev Apr 25, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Claude Code Hub Roadmap Apr 25, 2026
@ding113 ding113 deleted the fix/error-rule-regex-boundaries-20260425 branch May 13, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Error Rule area:provider bug Something isn't working size/M Medium PR (< 500 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant