Skip to content

Commit 7547280

Browse files
authored
fix(server): treat removed Bitbucket permissions endpoint as unknown, not blocking (#6525)
1 parent afca73d commit 7547280

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

apps/server/src/pullRequest/BitbucketPullRequestApi.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,46 @@ layer("BitbucketPullRequestApi.layer", (it) => {
867867
}),
868868
);
869869

870+
it.effect(
871+
"reads a removed permissions endpoint as granted rather than failing the merge on it",
872+
() =>
873+
Effect.gen(function* () {
874+
// Bitbucket retired /user/permissions/repositories under CHANGE-2770: every account now
875+
// gets HTTP 410 here, whatever it may do.
876+
mockedRequest.mockReturnValue(
877+
Effect.fail(
878+
new BitbucketApi.BitbucketResponseError({
879+
operation: "request",
880+
status: 410,
881+
responseBodyLength: 0,
882+
}),
883+
),
884+
);
885+
const api = yield* BitbucketPullRequestApi.BitbucketPullRequestApi;
886+
887+
assert.isTrue(yield* api.getRepositoryPermission({ repository: "acme/web" }));
888+
}),
889+
);
890+
891+
it.effect("still fails the permission read on a failure that is not the removed endpoint", () =>
892+
Effect.gen(function* () {
893+
mockedRequest.mockReturnValue(
894+
Effect.fail(
895+
new BitbucketApi.BitbucketResponseError({
896+
operation: "request",
897+
status: 401,
898+
responseBodyLength: 0,
899+
}),
900+
),
901+
);
902+
const api = yield* BitbucketPullRequestApi.BitbucketPullRequestApi;
903+
904+
const error = yield* Effect.flip(api.getRepositoryPermission({ repository: "acme/web" }));
905+
906+
assert.strictEqual(error._tag, "BitbucketResponseError");
907+
}),
908+
);
909+
870910
it.effect("reads the workspace's people and marks whoever is already a reviewer", () =>
871911
Effect.gen(function* () {
872912
mockedRequest

apps/server/src/pullRequest/BitbucketPullRequestApi.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ export type BitbucketPullRequestApiError =
107107
| BitbucketRepositoryUnsupportedError
108108
| BitbucketDiffCommitError;
109109

110+
/**
111+
* `/user/permissions/repositories` answering CHANGE-2770's removal notice rather than a
112+
* permission — Bitbucket sends this for every account now, not only ones it would have refused.
113+
*/
114+
function isRepositoryPermissionRemovedError(
115+
error: BitbucketPullRequestApiError,
116+
): error is BitbucketApi.BitbucketResponseError {
117+
return error._tag === "BitbucketResponseError" && error.status === 410;
118+
}
119+
110120
/**
111121
* Bitbucket's own ceiling. Asking for more does not fail — it answers with an empty page and no
112122
* error at all, so this is a number to respect rather than to push against.
@@ -553,6 +563,13 @@ export const make = Effect.gen(function* () {
553563
// Nothing on the repository, the pull request or the workspace states what the credentials
554564
// may do, so this endpoint is the one request Bitbucket makes unavoidable. It is asked
555565
// alongside the reads the detail was already making, so it costs no round trip of its own.
566+
//
567+
// Bitbucket permanently removed this endpoint (CHANGE-2770): every account now gets HTTP 410
568+
// in place of an answer, whatever it may do. That is the deprecated-endpoint signal, not a
569+
// permission being refused, so it is read the same way an unreachable read already is
570+
// elsewhere — as a permission that could not be learned, which grants rather than blocks, and
571+
// leaves the actual merge or write to say why if the account may not do it. Any other failure
572+
// (a bad token, a network fault, an unreadable body) still fails as it did before.
556573
getRepositoryPermission: (input) =>
557574
withRepository(input.repository, () =>
558575
readPage({
@@ -562,7 +579,7 @@ export const make = Effect.gen(function* () {
562579
)}`,
563580
decode: decodeRepositoryPermissionJson,
564581
}),
565-
),
582+
).pipe(Effect.catchIf(isRepositoryPermissionRemovedError, () => Effect.succeed(true))),
566583

567584
getPullRequestDiff: (input) =>
568585
input.commit !== undefined && !isCommitSha(input.commit)

0 commit comments

Comments
 (0)