fix(config): validate OBA server configs and drop invalid entries#112
fix(config): validate OBA server configs and drop invalid entries#112aaronbrethorst wants to merge 3 commits into
Conversation
A production service-discovery file with null feed URLs (gtfs_url, vehicle_position_url, agency_id) unmarshalled to empty strings, producing endless cryptic `Get "": unsupported protocol scheme ""` errors on every fetch cycle. - Add ValidateServer to check required fields (id, name, oba_base_url, oba_api_key, gtfs_url, vehicle_position_url, agency_id); trip_update_url and the GTFS-RT auth pair stay optional. - filterValidServers drops invalid servers and reports each to Sentry, so one bad entry can't block monitoring of the whole fleet. Wired into both loadConfigFromFile and loadConfigFromURL (covers startup + remote refresh). - Initialize Sentry before loading config in main.go, so startup-time validation/load errors are actually delivered instead of captured by an uninitialized hub.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds ChangesConfig Server Validation and Sentry Init
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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.
🧹 Nitpick comments (1)
internal/config/config_validation_test.go (1)
164-168: 💤 Low valueConsider checking the
w.Writeerror for linter compliance.While unchecked writes in test handlers are common practice, the static analysis tool flags line 166 for an unchecked error return. For consistency with project linting standards, consider:
🔧 Proposed fix
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - w.Write([]byte(body)) + if _, err := w.Write([]byte(body)); err != nil { + t.Errorf("Failed to write response: %v", err) + } }))🤖 Prompt for 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. In `@internal/config/config_validation_test.go` around lines 164 - 168, The w.Write call in the HTTP handler function returns an error that is currently unchecked, which causes a linter compliance issue. Capture the error return value from w.Write([]byte(body)) by assigning it to a variable or explicitly ignoring it with the blank identifier (_) to satisfy the linter requirements while maintaining the test handler logic.Source: Linters/SAST tools
🤖 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.
Nitpick comments:
In `@internal/config/config_validation_test.go`:
- Around line 164-168: The w.Write call in the HTTP handler function returns an
error that is currently unchecked, which causes a linter compliance issue.
Capture the error return value from w.Write([]byte(body)) by assigning it to a
variable or explicitly ignoring it with the blank identifier (_) to satisfy the
linter requirements while maintaining the test handler logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 32bdf4b5-cd10-4526-93eb-2848d1eae393
📒 Files selected for processing (6)
CLAUDE.mdcmd/watchdog/main.gointernal/config/config_loader.gointernal/config/config_loader_test.gointernal/config/config_validation.gointernal/config/config_validation_test.go
Addresses CodeRabbit linter nitpick on PR #112.
Summary
nullfeed URLs (gtfs_url,vehicle_position_url,agency_id). Go unmarshals JSONnullinto a string field as"", which produced crypticGet "": unsupported protocol scheme ""errors on every fetch cycle for the affected servers (33, 41, 43, 36, 19).ValidateServer(required:id,name,oba_base_url,oba_api_key,gtfs_url,vehicle_position_url,agency_id;trip_update_urland the GTFS-RT auth pair are optional) andfilterValidServers, which drops invalid servers and reports each to Sentry — one bad entry can't block monitoring of the rest of the fleet. Wired into bothloadConfigFromFileandloadConfigFromURL, so it covers startup and the periodic remote-config refresh.main.go. Previously config load/validation ran ~30 lines beforeSetupSentry(), so startup-time error reports were captured by an uninitialized hub and silently lost — exactly the partial-misconfig case this fix targets.CLAUDE.mdcommit already on this branch.Test plan
go test ./...— full suite greenValidateServer(valid, each required field, whitespace-only, all-missing production mirror),filterValidServers(interleaved valid/invalid ordering, all-invalid, empty), and filtering coverage for both the file and URL loadersunsupported protocol schemeerror; the well-formed server flows through normallyNo servers found in configuration.go vet ./...clean,gofmtclean, binary builds withCGO_ENABLED=0Review notes (non-blocking)
sentry.LevelError(consistent with the loaders' existing reports). A reviewer may preferLevelWarningfor routine single-entry drops, plus a single summary signal that conveys the ratio dropped (e.g. "45 of 50") so a near-total config collapse is distinguishable from one bad entry. Left as-is to match current package conventions.*slog.Logger, so drops are reported only to Sentry, not the structured logs. Surfacing a "loaded N of M servers, dropped K" summary via the logger inmain.go/refreshConfig(which do hold loggers) would require threading a drop count back out of the loaders — deferred to keep this PR scoped.null. This PR makes watchdog resilient to that input but doesn't fix the generator.Summary by CodeRabbit