Skip to content

Commit 5d5a1bf

Browse files
authored
Improve error handling for App Hosting compute service account (#8815)
* improve error handling for compute sa * throw FirebaseError for unexpected error
1 parent 69c486b commit 5d5a1bf

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

src/apphosting/backend.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ describe("apphosting setup functions", () => {
215215
expect(createServiceAccountStub).to.be.calledOnce;
216216
expect(addServiceAccountToRolesStub).to.not.be.called;
217217
});
218+
219+
it("should throw an unexpected error", async () => {
220+
testResourceIamPermissionsStub.rejects(
221+
new FirebaseError("Unexpected error", { status: 500 }),
222+
);
223+
224+
await expect(
225+
ensureAppHostingComputeServiceAccount(projectId, serviceAccount),
226+
).to.be.rejectedWith("Unexpected error");
227+
228+
expect(testResourceIamPermissionsStub).to.be.calledOnce;
229+
expect(createServiceAccountStub).to.not.be.called;
230+
expect(addServiceAccountToRolesStub).to.not.be.called;
231+
});
218232
});
219233

220234
describe("deleteBackendAndPoll", () => {

src/apphosting/backend.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,17 @@ export async function ensureAppHostingComputeServiceAccount(
266266
} catch (err: unknown) {
267267
if (!(err instanceof FirebaseError)) {
268268
throw err;
269-
} else if (err.status === 403) {
269+
}
270+
if (err.status === 403) {
270271
throw new FirebaseError(
271272
`Failed to create backend due to missing delegation permissions for ${sa}. Make sure you have the iam.serviceAccounts.actAs permission.`,
272273
{ original: err },
273274
);
275+
} else if (err.status !== 404) {
276+
throw new FirebaseError(
277+
"Unexpected error occurred while testing for IAM service account permissions",
278+
{ original: err },
279+
);
274280
}
275281
}
276282
await provisionDefaultComputeServiceAccount(projectId);
@@ -373,7 +379,7 @@ async function provisionDefaultComputeServiceAccount(projectId: string): Promise
373379
} catch (err: unknown) {
374380
if (getErrStatus(err) === 400) {
375381
logWarning(
376-
"Your App Hosting compute service account is still being provisioned in the background; you may continue with the init flow.",
382+
"Your App Hosting compute service account is still being provisioned in the background. If you encounter an error, please try again after a few moments.",
377383
);
378384
} else {
379385
throw err;

src/deploy/apphosting/prepare.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { needProjectId } from "../../projectUtils";
1212
import { checkbox, confirm } from "../../prompt";
1313
import { logLabeledBullet, logLabeledWarning } from "../../utils";
1414
import { Context } from "./args";
15-
import { FirebaseError } from "../../error";
1615

1716
/**
1817
* Prepare backend targets to deploy from source. Checks that all required APIs are enabled,
@@ -22,17 +21,7 @@ export default async function (context: Context, options: Options): Promise<void
2221
const projectId = needProjectId(options);
2322
await ensureApiEnabled(options);
2423
await ensureRequiredApisEnabled(projectId);
25-
try {
26-
await ensureAppHostingComputeServiceAccount(projectId, /* serviceAccount= */ "");
27-
} catch (err) {
28-
if ((err as FirebaseError).status === 400) {
29-
logLabeledWarning(
30-
"apphosting",
31-
"Your App Hosting compute service account is still being provisioned. Please try again in a few moments.",
32-
);
33-
}
34-
throw err;
35-
}
24+
await ensureAppHostingComputeServiceAccount(projectId, /* serviceAccount= */ "");
3625

3726
context.backendConfigs = new Map<string, AppHostingSingle>();
3827
context.backendLocations = new Map<string, string>();

0 commit comments

Comments
 (0)