diff --git a/parser/ossinsight.go b/parser/ossinsight.go index b516723..96b41c2 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,19 @@ 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) + } + // 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 for _, row := range apiRes.Data.Rows { if !isEnglishText(row.Description) {