diff --git a/internal/proxy/graphql.go b/internal/proxy/graphql.go index 421eb473..10020965 100644 --- a/internal/proxy/graphql.go +++ b/internal/proxy/graphql.go @@ -155,6 +155,7 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s if v, ok := variables["repo"].(string); ok && repo == "" { repo = v } + logGraphQL.Printf("extractOwnerRepo: from variables: owner=%q repo=%q", owner, repo) } // Fall back to parsing the query string @@ -166,6 +167,7 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s if m[2] != "" && repo == "" { repo = m[2] } + logGraphQL.Printf("extractOwnerRepo: from query regex: owner=%q repo=%q", owner, repo) } } @@ -187,19 +189,34 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s // searchQueryArgPattern extracts the literal query string from search(query:"...", ...) var searchQueryArgPattern = regexp.MustCompile(`(?i)\bsearch\s*\(\s*query\s*:\s*"([^"]+)"`) +// truncateForLog truncates s to at most maxRunes runes, for safe debug logging. +func truncateForLog(s string, maxRunes int) string { + if maxRunes <= 0 { + return "" + } + r := []rune(s) + if len(r) <= maxRunes { + return s + } + return string(r[:maxRunes]) +} + // extractSearchQuery returns the search query argument from a GraphQL search // query. It checks variables ($query) first, then inline query text. func extractSearchQuery(query string, variables map[string]interface{}) string { // Check variables for $query if variables != nil { if v, ok := variables["query"].(string); ok && v != "" { + logGraphQL.Printf("extractSearchQuery: found in variables: %q", truncateForLog(v, 80)) return v } } // Parse inline: search(query:"repo:owner/name is:issue", ...) if m := searchQueryArgPattern.FindStringSubmatch(query); m != nil { + logGraphQL.Printf("extractSearchQuery: found inline: %q", truncateForLog(m[1], 80)) return m[1] } + logGraphQL.Print("extractSearchQuery: no search query found") return "" }