Skip to content

Commit 774d3f0

Browse files
authored
Change how FDC determines whether creating a CSQL free trial is allowed. (#8065)
* Fix log statements. * Catch backend quota error instead of querying for free trial metric.
1 parent ce14fa6 commit 774d3f0

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

src/dataconnect/freeTrial.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -35,33 +35,40 @@ export async function getFreeTrialInstanceId(projectId: string): Promise<string
3535
return instances.find((i) => i.settings.userLabels?.["firebase-data-connect"] === "ft")?.name;
3636
}
3737

38+
export async function isFreeTrialError(err: any, projectId: string): Promise<boolean> {
39+
// checkFreeTrialInstanceUsed is also called to ensure the request didn't fail due to an unrelated quota issue.
40+
return err.message.includes("Quota Exhausted") && (await checkFreeTrialInstanceUsed(projectId))
41+
? true
42+
: false;
43+
}
44+
3845
export function printFreeTrialUnavailable(
3946
projectId: string,
4047
configYamlPath: string,
4148
instanceId?: string,
4249
): void {
4350
if (!instanceId) {
4451
utils.logLabeledError(
45-
"data connect",
52+
"dataconnect",
4653
"The CloudSQL free trial has already been used on this project.",
4754
);
4855
utils.logLabeledError(
49-
"data connect",
56+
"dataconnect",
5057
`You may create or use a paid CloudSQL instance by visiting https://console.cloud.google.com/sql/instances`,
5158
);
5259
return;
5360
}
5461
utils.logLabeledError(
55-
"data connect",
62+
"dataconnect",
5663
`Project '${projectId} already has a CloudSQL instance '${instanceId}' on the Firebase Data Connect no-cost trial.`,
5764
);
5865
const reuseHint =
5966
`To use a different database in the same instance, ${clc.bold(`change the ${clc.blue("instanceId")} to "${instanceId}"`)} and update ${clc.blue("location")} in ` +
6067
`${clc.green(configYamlPath)}.`;
6168

62-
utils.logLabeledError("data connect", reuseHint);
69+
utils.logLabeledError("dataconnect", reuseHint);
6370
utils.logLabeledError(
64-
"data connect",
71+
"dataconnect",
6572
`Alternatively, you may create a new (paid) CloudSQL instance at https://console.cloud.google.com/sql/instances`,
6673
);
6774
}

src/dataconnect/provisionCloudSql.ts

+31-27
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
getFreeTrialInstanceId,
1212
freeTrialTermsLink,
1313
printFreeTrialUnavailable,
14-
checkFreeTrialInstanceUsed,
14+
isFreeTrialError,
1515
} from "./freeTrial";
1616
import { FirebaseError } from "../error";
1717

@@ -69,11 +69,6 @@ export async function provisionCloudSql(args: {
6969
if (err.status !== 404) {
7070
throw err;
7171
}
72-
const freeTrialInstanceId = await getFreeTrialInstanceId(projectId);
73-
if (await checkFreeTrialInstanceUsed(projectId)) {
74-
printFreeTrialUnavailable(projectId, configYamlPath, freeTrialInstanceId);
75-
throw new FirebaseError("No-cost Cloud SQL trial has already been used on this project.");
76-
}
7772
const cta = dryRun ? "It will be created on your next deploy" : "Creating it now.";
7873
silent ||
7974
utils.logLabeledBullet(
@@ -84,27 +79,36 @@ export async function provisionCloudSql(args: {
8479
`\nMonitor the progress at ${cloudSqlAdminClient.instanceConsoleLink(projectId, instanceId)}`,
8580
);
8681
if (!dryRun) {
87-
const newInstance = await promiseWithSpinner(
88-
() =>
89-
cloudSqlAdminClient.createInstance(
90-
projectId,
91-
locationId,
92-
instanceId,
93-
enableGoogleMlIntegration,
94-
waitForCreation,
95-
),
96-
"Creating your instance...",
97-
);
98-
if (newInstance) {
99-
silent || utils.logLabeledBullet("dataconnect", "Instance created");
100-
connectionName = newInstance?.connectionName || "";
101-
} else {
102-
silent ||
103-
utils.logLabeledBullet(
104-
"dataconnect",
105-
"Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy.",
106-
);
107-
return connectionName;
82+
try {
83+
const newInstance = await promiseWithSpinner(
84+
() =>
85+
cloudSqlAdminClient.createInstance(
86+
projectId,
87+
locationId,
88+
instanceId,
89+
enableGoogleMlIntegration,
90+
waitForCreation,
91+
),
92+
"Creating your instance...",
93+
);
94+
if (newInstance) {
95+
silent || utils.logLabeledBullet("dataconnect", "Instance created");
96+
connectionName = newInstance?.connectionName || "";
97+
} else {
98+
silent ||
99+
utils.logLabeledBullet(
100+
"dataconnect",
101+
"Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy.",
102+
);
103+
return connectionName;
104+
}
105+
} catch (err: any) {
106+
if (await isFreeTrialError(err, projectId)) {
107+
const freeTrialInstanceId = await getFreeTrialInstanceId(projectId);
108+
printFreeTrialUnavailable(projectId, configYamlPath, freeTrialInstanceId);
109+
throw new FirebaseError("No-cost Cloud SQL trial has already been used on this project.");
110+
}
111+
throw err;
108112
}
109113
}
110114
}

0 commit comments

Comments
 (0)