Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 15, 2025

  • Extract isGitHubError type guard to improve code clarity
  • Add proper TypeScript interface for GitHub error response structure
  • Refactor error checking logic to use the new type guard
  • All tests pass successfully
Original prompt

When the GitHubClient is used to create a new PR, it should check for failures with this payload {
"resource": "PullRequest",
"field": "base",
"code": "invalid"
} and turn that into an error that indicates that stacked PRs across forks aren't possible as the base doesn't exist in the fork.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI assigned Copilot and Byron Oct 15, 2025
Copy link

vercel bot commented Oct 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
gitbutler-web Ready Ready Preview Comment Oct 15, 2025 9:24am

@Copilot Copilot AI changed the title [WIP] Add error handling for invalid base in PR creation Add detection for stacked PRs across forks error in GitHub API responses Oct 15, 2025
@Copilot Copilot AI requested a review from Byron October 15, 2025 03:38
Copilot finished work on behalf of Byron October 15, 2025 03:38
@Byron Byron force-pushed the copilot/check-failure-for-stacked-prs branch from 8386d65 to 9371137 Compare October 15, 2025 04:51
@Byron
Copy link
Collaborator

Byron commented Oct 15, 2025

@estib-vega I took a good look at the code and it seems sound, while solving the stated problem at least according to the tests. I don't know though if this is the right approach at all.

Is this salvageable?
Thanks again

Copy link
Contributor

@mtsgrd mtsgrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking pretty good!

Comment on lines 74 to 105
test('should not detect stacked PR error for other validation errors', async () => {
const mockError = {
message: 'Validation Failed',
response: {
data: {
message: 'Validation Failed',
errors: [
{
resource: 'PullRequest',
field: 'title',
code: 'missing'
}
]
}
}
};

vi.spyOn(octokit.pulls, 'create').mockRejectedValue(mockError);

try {
await service?.createPr({
title: 'Test PR',
body: 'Test body',
draft: false,
baseBranchName: 'feature-branch',
upstreamName: 'my-branch'
});
expect.fail('Should have thrown an error');
} catch (err: any) {
expect(err.code).not.toBe(Code.GitHubStackedPrFork);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could manually remove this test case, it feels unnecessary.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done.

Comment on lines 88 to 108
const message = isErrorlike(err) ? err.message : String(err);
const code = message.startsWith('Not Found -') ? Code.GitHubTokenExpired : undefined;

// Check for stacked PR across forks error (base field invalid)
let code: string | undefined;
if (isErrorlike(err) && 'response' in err) {
const response = (err as any).response;
if (response?.data?.errors instanceof Array) {
const hasInvalidBaseError = response.data.errors.some(
(error: any) =>
error.resource === 'PullRequest' && error.field === 'base' && error.code === 'invalid'
);
if (hasInvalidBaseError) {
code = Code.GitHubStackedPrFork;
}
}
}

// Check for expired token
if (!code && message.startsWith('Not Found -')) {
code = Code.GitHubTokenExpired;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block could be improved extracting a type guard called isGitHubError.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Extract the type guard as isGitHubError.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted the type guard as isGitHubError with a proper GitHubErrorResponse interface. This improves type safety and makes the error checking logic more readable. Commit: Extract isGitHubError type guard as suggested

@Byron
Copy link
Collaborator

Byron commented Oct 15, 2025

Thanks for the review @mtsgrd. I did what I could and hope the copilot comes back with the type guard extraction. Can I ask you to take it from there to get it merged if good?
You should be able to push into this PR without problems.

PS: The first time I see how this works, but looks like Copilot just runs as part of an action :): https://github.com/gitbutlerapp/gitbutler/actions/runs/18523828069/job/52789809376 (this particular one is also failing with 500 server error, maybe due to a vibe-coded server ;)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants