Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions pkg/errors/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package errors
import (
"context"
"fmt"
"net/http"

"github.com/github/github-mcp-server/pkg/utils"
"github.com/google/go-github/v79/github"
Expand Down Expand Up @@ -44,10 +45,25 @@ func (e *GitHubGraphQLError) Error() string {
return fmt.Errorf("%s: %w", e.Message, e.Err).Error()
}

type GitHubRawAPIError struct {
Message string `json:"message"`
Response *http.Response `json:"-"`
Err error `json:"-"`
}

func newGitHubRawAPIError(message string, resp *http.Response, err error) *GitHubRawAPIError {
return &GitHubRawAPIError{
Message: message,
Response: resp,
Err: err,
}
}

type GitHubErrorKey struct{}
type GitHubCtxErrors struct {
api []*GitHubAPIError
graphQL []*GitHubGraphQLError
raw []*GitHubRawAPIError
}

// ContextWithGitHubErrors updates or creates a context with a pointer to GitHub error information (to be used by middleware).
Expand Down Expand Up @@ -107,6 +123,15 @@ func addGitHubGraphQLErrorToContext(ctx context.Context, err *GitHubGraphQLError
return nil, fmt.Errorf("context does not contain GitHubCtxErrors")
}

func addRawAPIErrorToContext(ctx context.Context, err *GitHubRawAPIError) (context.Context, error) {
if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok {
val.raw = append(val.raw, err)
return ctx, nil
}

return nil, fmt.Errorf("context does not contain GitHubCtxErrors")
}

// NewGitHubAPIErrorResponse returns an mcp.NewToolResultError and retains the error in the context for access via middleware
func NewGitHubAPIErrorResponse(ctx context.Context, message string, resp *github.Response, err error) *mcp.CallToolResult {
apiErr := newGitHubAPIError(message, resp, err)
Expand All @@ -124,3 +149,11 @@ func NewGitHubGraphQLErrorResponse(ctx context.Context, message string, err erro
}
return utils.NewToolResultErrorFromErr(message, err)
}

func NewGitHubRawAPIErrorResponse(ctx context.Context, message string, resp *http.Response, err error) *mcp.CallToolResult {
rawAPIErr := newGitHubRawAPIError(message, resp, err)
if ctx != nil {
_, _ = addRawAPIErrorToContext(ctx, rawAPIErr) // Explicitly ignore error for graceful handling
}
return utils.NewToolResultErrorFromErr(message, err)
}
2 changes: 1 addition & 1 deletion pkg/github/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
}
resp, err := rawClient.GetRawContent(ctx, owner, repo, path, rawOpts)
if err != nil {
return utils.NewToolResultError("failed to get raw repository content"), nil, nil
return ghErrors.NewGitHubRawAPIErrorResponse(ctx, "failed to get raw repository content", resp, err), nil, nil
}
defer func() {
_ = resp.Body.Close()
Expand Down