searchIssuesHandler runs the REST issues search, enriches each hit with custom field values fetched via a single follow-up GraphQL nodes() query, and applies any post-process options (e.g. IFC labelling).
(ctx context.Context, deps ToolDependencies, args map[string]any, options ...searchOption)
| 1760 | // fetched via a single follow-up GraphQL nodes() query, and applies any post-process options |
| 1761 | // (e.g. IFC labelling). |
| 1762 | func searchIssuesHandler(ctx context.Context, deps ToolDependencies, args map[string]any, options ...searchOption) (*mcp.CallToolResult, error) { |
| 1763 | const errorPrefix = "failed to search issues" |
| 1764 | |
| 1765 | query, opts, err := prepareSearchArgs(args, "issue") |
| 1766 | if err != nil { |
| 1767 | return utils.NewToolResultError(err.Error()), nil |
| 1768 | } |
| 1769 | |
| 1770 | client, err := deps.GetClient(ctx) |
| 1771 | if err != nil { |
| 1772 | return utils.NewToolResultErrorFromErr(errorPrefix+": failed to get GitHub client", err), nil |
| 1773 | } |
| 1774 | result, resp, err := client.Search.Issues(ctx, query, opts) |
| 1775 | if err != nil { |
| 1776 | return utils.NewToolResultErrorFromErr(errorPrefix, err), nil |
| 1777 | } |
| 1778 | defer func() { _ = resp.Body.Close() }() |
| 1779 | |
| 1780 | if resp.StatusCode != http.StatusOK { |
| 1781 | body, err := io.ReadAll(resp.Body) |
| 1782 | if err != nil { |
| 1783 | return utils.NewToolResultErrorFromErr(errorPrefix+": failed to read response body", err), nil |
| 1784 | } |
| 1785 | return ghErrors.NewGitHubAPIStatusErrorResponse(ctx, errorPrefix, resp, body), nil |
| 1786 | } |
| 1787 | |
| 1788 | var fieldValuesByID map[string][]MinimalFieldValue |
| 1789 | if len(result.Issues) > 0 { |
| 1790 | gqlClient, err := deps.GetGQLClient(ctx) |
| 1791 | if err != nil { |
| 1792 | return utils.NewToolResultErrorFromErr(errorPrefix+": failed to get GitHub GraphQL client", err), nil |
| 1793 | } |
| 1794 | fieldValuesByID, err = fetchIssueFieldValuesByNodeID(ctx, gqlClient, result.Issues) |
| 1795 | if err != nil { |
| 1796 | return ghErrors.NewGitHubGraphQLErrorResponse(ctx, errorPrefix+": failed to fetch issue field values", err), nil |
| 1797 | } |
| 1798 | } |
| 1799 | |
| 1800 | items := make([]SearchIssueResult, 0, len(result.Issues)) |
| 1801 | for _, iss := range result.Issues { |
| 1802 | hit := SearchIssueResult{Issue: iss} |
| 1803 | if iss != nil && iss.NodeID != nil { |
| 1804 | hit.FieldValues = fieldValuesByID[*iss.NodeID] |
| 1805 | } |
| 1806 | items = append(items, hit) |
| 1807 | } |
| 1808 | |
| 1809 | response := SearchIssuesResponse{ |
| 1810 | Total: result.Total, |
| 1811 | IncompleteResults: result.IncompleteResults, |
| 1812 | Items: items, |
| 1813 | } |
| 1814 | |
| 1815 | r, err := json.Marshal(response) |
| 1816 | if err != nil { |
| 1817 | return utils.NewToolResultErrorFromErr(errorPrefix+": failed to marshal response", err), nil |
| 1818 | } |
| 1819 |
no test coverage detected