[FIX#508] parser rule.Error 의 Host 필드 누락 보정 — stale_relearn / host failure counter 정상화 - #509
Conversation
…ter 키 정상화 (이슈 #508) - 라이브 회차에서 v.daum.net 81건 + news.daum.net 34건 등 page parse 실패가 누적됐음에도 staleCounter.Record 가 단 한 번도 호출되지 않은 원인 - parser.go / discovery.go / extract.go 의 14개 `&Error{}` 발산이 URL 만 채우고 Host 누락 → handleRuleError → recordStaleAndMaybeRelearn 의 host=="" 가드에 막힘 - 신규 헬퍼 errorHost(rawURL): resolver 와 동일한 canonical 정규화 (u.Hostname() + lowercase) — port 제거 + 대소문자 일관성으로 staleCounter / failureCounter 키 매칭 보장 - 14개 Error 발산 지점 모두에 Host: errorHost(raw.URL) 명시 설정 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 정공법은 parser.go 측에서 Host 필드 명시 설정이지만, 향후 새 Error 발산 지점에서 누락하더라도 stale_relearn / chromedp 자동 전환이 무력화되지 않도록 fail-safe - handleRuleError 진입 직후 rerr.Host == "" 면 hostOf(raw.URL) 로 backfill — 이후 LLM enqueue + recordHostFailure + recordStaleAndMaybeRelearn 모두 정상 host 사용 - worker 의 hostOf 도 resolver / parser.errorHost 와 같은 canonical form (u.Hostname() + lowercase) 으로 정규화 — counter 키 일관성 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ParsePage / ParseLinks 의 각 에러 경로 (ErrEmptySelector / ErrParseFailure / nil-rule ErrNoRule / validateRaw 빈 raw) 에서 rerr.Host 가 canonical host 로 설정되는지 검증 - 정규화 검증: 대문자 host 입력 → lowercase, port 포함 host → port 제거 - 라이브 회차에서 staleCounter 가 한 번도 발화하지 않은 회귀 재발 방지 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR fixes a critical bug where the ChangesError Host Field Propagation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
이슈 #508 수정 PR로, rule.Error 구조체에 Host 필드를 빠뜨려 worker 의 staleCounter / failureCounter 가 빈 host 가드에 막혀 무력화되던 회귀를 바로잡습니다. parser/discovery/extract 의 14개 &Error{} 발산 지점 모두 Host 를 채우고, worker 측에는 fallback 보호 및 host 정규화(lowercase) 통일을 추가합니다.
Changes:
parser.go/discovery.go/extract.go의 모든&Error{}발산에Host: errorHost(raw.URL)명시 +errorHost헬퍼 신설 (canonical:u.Hostname()+ lowercase)worker.handleRuleError에rerr.Host == ""시hostOf(raw.URL)로 backfill,hostOf도 lowercase 통일- parser 에러 경로별
rerr.Host검증 단위 테스트 8건 추가
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| internal/processor/parser/rule/parser.go | errorHost 헬퍼 추가, ParsePage/ParseLinks 9개 Error 발산 지점에 Host 설정 |
| internal/processor/parser/rule/discovery.go | PageLinkDiscovery 의 4개 Error 발산에 Host 설정 |
| internal/processor/parser/rule/extract.go | validateRaw 의 Error 발산에 Host 설정 |
| internal/processor/parser/worker/worker.go | handleRuleError 의 Host fallback 추가, hostOf 에 lowercase 정규화 |
| test/internal/processor/parser/rule/parser_test.go | Host 필드 채움/정규화 검증 단위 테스트 8건 추가 |
There was a problem hiding this comment.
Code Review
This pull request implements canonical host extraction for rule.Error objects to ensure consistent error tracking across different components, addressing issue #508. The changes include adding an errorHost helper in the rule package, updating error returns to include the normalized host, and aligning the worker package's hostOf function with this canonical format. Comprehensive tests were added to verify host normalization, including lowercase conversion and port removal. Feedback recommends consolidating the duplicated host normalization logic into a single exported function to ensure a single source of truth and removing a redundant nil check in the errorHost function.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/internal/processor/parser/rule/parser_test.go`:
- Around line 348-360: The test TestParser_ParsePage_ErrorHost_LowercasesHost
only asserts rerr.Host and can pass for other error codes; update it to assert
the specific error code (rule.ErrEmptySelector) before checking Host by adding
require.Equal(t, rule.ErrEmptySelector, rerr.Code) (or
require.ErrorIs/require.True with errors.Is(rerr, rule.ErrEmptySelector) if rerr
implements error wrapping) immediately after require.ErrorAs, then keep the Host
assertion; apply the same change to the sibling test covering lines 362-374 (the
other ParsePage error-host normalization test) so both pin the expected error
code.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: b3b0f47e-06bd-40c2-8ef9-96e287054098
📒 Files selected for processing (5)
internal/processor/parser/rule/discovery.gointernal/processor/parser/rule/extract.gointernal/processor/parser/rule/parser.gointernal/processor/parser/worker/worker.gotest/internal/processor/parser/rule/parser_test.go
- errorHost → rule.NormalizeHost 로 승격 (exported, single source of truth) - parser.go / discovery.go / extract.go 의 14개 발산 모두 rule.NormalizeHost 사용 - discovery.go 의 legacy hostOf (lowercase / port 정규화 누락) 제거 — same-origin 비교도 NormalizeHost 로 통일 - worker.go hostOf 를 rule.NormalizeHost 의 thin wrapper 로 변경 — 패키지 경계 넘어서도 동일 canonical form - url.Parse 후 u == nil 가드 제거 (err nil 시 항상 non-nil — gemini 지적) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Host 단정만으로 통과하는 케이스 회피 — 의도된 ErrEmptySelector 경로가 아닌 다른 에러 (예: ErrNoRule) 로 흘러도 PASS 되던 시나리오 잠금 - TestParser_ParsePage_ErrorHost_LowercasesHost / TestParser_ParsePage_ErrorHost_StripsPort 에 assert.Equal(t, rule.ErrEmptySelector, rerr.Code) 추가 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
연관 이슈
구현 내용
라이브 회차 분석에서 v.daum.net 81건 + news.daum.net 34건 등 ~221건 page parse 실패가 누적됐음에도 stale_relearn 메커니즘이 단 한 번도 발화하지 않은 회귀 수정.
근본 원인
internal/processor/parser/rule/parser.go/discovery.go/extract.go의 14개&Error{}발산 모두URL: raw.URL만 채우고Host필드 누락. →handleRuleError→recordStaleAndMaybeRelearn의host == ""가드에 막혀staleCounter.Record가 호출되지 않음.비교:
resolver.go의 ErrNoRule 두 지점만 정상 설정 (그래서 resolver 발산 ErrNoRule 흐름은 정상 동작).변경 요약
1) 정공법 — parser.go / discovery.go / extract.go 의 모든 Error 발산에 Host 명시 설정 (commit f03a203)
errorHost(rawURL string) string— resolver 의extractHostPath와 동일한 canonical 정규화 (u.Hostname()+strings.ToLower)Host: errorHost(raw.URL)추가:parser.go9개 (ParsePage 4개 + ParseLinks 5개)discovery.go4개 (PageLinkDiscovery)extract.go1개 (validateRaw)2) 방어책 — worker.go fallback (commit 0d804b0)
handleRuleError진입 직후rerr.Host == "" && raw != nil이면hostOf(raw.URL)로 backfillhostOf도strings.ToLower추가 — resolver / parser.errorHost 와 canonical form 일치 (counter 키 일관성)3) 단위 테스트 (commit 3407a34)
rerr.Host가 정상 설정되는지 검증라이브 검증 가능 지표
다음 라이브 회차에서 확인 (LLM quota 정상 상태 전제):
"stale rule failure recorded"(DEBUG) 또는"stale rule threshold reached — LLM relearn trigger eligible"(INFO) 로그 실제 발생CI / 머지 게이트 점검
변경 영향 범위
internal/processor/parser/rule(parser.go / discovery.go / extract.go — Error 발산 14개)internal/processor/parser/worker(handleRuleError fallback + hostOf 정규화)Low— 기존 호출 시그니처 / 메시지 / 에러 코드 동일, Host 필드만 추가. 정규화 변경 (worker hostOf 의 lowercase) 은 resolver/parser.errorHost 와 일관성 통일이라 회귀 위험 낮음.Required Status Checks
Commit LintPR Title LintLinked Issue CheckFormat CheckBuildTestLint롤백 계획
🤖 Generated with Claude Code
Summary by CodeRabbit
Improvements
Tests