From d5fa3e781da6998791b22a5be395809cd8be5e94 Mon Sep 17 00:00:00 2001 From: sigmanor Date: Tue, 8 Sep 2026 12:33:15 +0300 Subject: [PATCH 1/2] fix(parser): fail loudly when the OssInsight ranking is unavailable OssInsight paused its star-based rankings: the trends endpoint answers with HTTP 200, an empty `data.rows` and a `data_quality` block explaining that the metric cannot be computed. The parser only read `data.rows`, so a collect run returned an empty repository list and reported success, which made the scheduled collect fetch nothing without a single error in the logs. Parse `data_quality` and return an error when the metric is not ok, or when the response carries no rows at all. `data.rows` is checked instead of the filtered slice, so an all-non-English page stays a legitimate empty result. --- parser/ossinsight.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/parser/ossinsight.go b/parser/ossinsight.go index b516723..ff7ed87 100644 --- a/parser/ossinsight.go +++ b/parser/ossinsight.go @@ -41,6 +41,12 @@ type OssInsightResponse struct { Forks string `json:"forks"` } `json:"rows"` } `json:"data"` + DataQuality struct { + Status string `json:"status"` + Metric string `json:"metric"` + UnavailableSince string `json:"unavailable_since"` + Reason string `json:"reason"` + } `json:"data_quality"` } func GetTrendingReposFromOssInsight(maxRepos int, period, language string) ([]Repository, error) { @@ -87,6 +93,15 @@ func GetTrendingReposFromOssInsight(maxRepos int, period, language string) ([]Re return nil, fmt.Errorf("failed to decode OssInsight response: %v", err) } + // OssInsight answers with HTTP 200 and no rows when the ranking it is asked + // for cannot be computed, so the payload has to be checked explicitly. + if q := apiRes.DataQuality; q.Status != "" && q.Status != "ok" { + return nil, fmt.Errorf("OssInsight metric %q is %s since %s: %s", q.Metric, q.Status, q.UnavailableSince, q.Reason) + } + if len(apiRes.Data.Rows) == 0 { + return nil, fmt.Errorf("OssInsight returned no trending repositories for period %q, language %q", period, language) + } + var allRepos []Repository for _, row := range apiRes.Data.Rows { if !isEnglishText(row.Description) { From 4d6932a3fcbd87cf5e716d4d811a4c34239194e9 Mon Sep 17 00:00:00 2001 From: sigmanor Date: Tue, 8 Sep 2026 12:55:38 +0300 Subject: [PATCH 2/2] fix(parser): let a narrow OssInsight query come back empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The empty-payload guard fired for any request with no rows, including one that is legitimately empty: `language` is not validated against an allow-list, so a narrow filter reaching a healthy OssInsight can match nothing at all. That made the two collect sources disagree on the same class of input — GetTrendingRepos returns an empty slice when the GitHub trending page has no matches, while this path answered with a 500. Restrict the guard to an unfiltered query, where no rows can only mean the ranking is broken. The check still covers the case data_quality is missing from the response. --- parser/ossinsight.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/parser/ossinsight.go b/parser/ossinsight.go index ff7ed87..96b41c2 100644 --- a/parser/ossinsight.go +++ b/parser/ossinsight.go @@ -98,8 +98,12 @@ func GetTrendingReposFromOssInsight(maxRepos int, period, language string) ([]Re if q := apiRes.DataQuality; q.Status != "" && q.Status != "ok" { return nil, fmt.Errorf("OssInsight metric %q is %s since %s: %s", q.Metric, q.Status, q.UnavailableSince, q.Reason) } - if len(apiRes.Data.Rows) == 0 { - return nil, fmt.Errorf("OssInsight returned no trending repositories for period %q, language %q", period, language) + // A narrow language filter can legitimately match nothing, the same way the + // GitHub trending page can come back empty, so only an unfiltered query that + // yields nothing is treated as a failure. This keeps the empty-payload guard + // useful even if the data_quality block ever disappears from the response. + if len(apiRes.Data.Rows) == 0 && (language == "" || language == "All") { + return nil, fmt.Errorf("OssInsight returned no trending repositories for period %q", period) } var allRepos []Repository