Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions src/deploy/functions/release/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function parseErrorCode(err: any): number {
err.status ||
err.code ||
err.context?.response?.statusCode ||
err.original?.status ||
err.original?.code ||
err.original?.context?.response?.statusCode
);
Expand Down
5 changes: 3 additions & 2 deletions src/gcp/cloudfunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,15 @@ export function captureRuntimeValidationError(errMessage: string): string {
* @param err The error returned from the operation.
*/
function functionsOpLogReject(funcName: string, type: string, err: any): void {
const status = err?.context?.response?.statusCode || err?.status;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

While err.status is expected to be a number from FirebaseError, the type of err is any, which doesn't guarantee this. If err.status were a non-numeric string (e.g., an error status string like 'RESOURCE_EXHAUSTED'), it would be assigned to status. This could lead to incorrect behavior, as status === 429 would fail and a non-numeric value would be passed to the FirebaseError constructor, which expects a number. To make this more robust, consider ensuring the extracted value is a number.

Suggested change
const status = err?.context?.response?.statusCode || err?.status;
const code = err?.context?.response?.statusCode || err?.status;
const status = typeof code === "number" ? code : undefined;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error paths feeding these handlers already give us numeric status codes: responseToError sets statusCode as a number, gax errors use numeric code, and FirebaseError stores a numeric status (default 500). If a strange upstream ever handed us a string like "RESOURCE_EXHAUSTED", the 429 check would simply skip the quota branch and the FirebaseError would carry that string, but it wouldn’t change retry behavior because the executor’s parseErrorCode still looks for numeric codes.

// Sniff for runtime validation errors and log a more user-friendly warning.
if ((err?.message as string).includes("Runtime validation errors")) {
const capturedMessage = captureRuntimeValidationError(err.message);
utils.logWarning(
clc.bold(clc.yellow("functions:")) + " " + capturedMessage + " for function " + funcName,
);
}
if (err?.context?.response?.statusCode === 429) {
if (status === 429) {
utils.logWarning(
`${clc.bold(
clc.yellow("functions:"),
Expand All @@ -193,7 +194,7 @@ function functionsOpLogReject(funcName: string, type: string, err: any): void {
}
throw new FirebaseError(`Failed to ${type} function ${funcName}`, {
original: err,
status: err?.context?.response?.statusCode,
status,
context: { function: funcName },
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/gcp/cloudfunctionsv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ interface GenerateUploadUrlResponse {
* @param err The error returned from the operation.
*/
function functionsOpLogReject(func: InputCloudFunction, type: string, err: any): void {
const status = err?.context?.response?.statusCode || err?.status;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the v1 file, err.status is not guaranteed to be a number since err is of type any. If it were a string, it could cause issues with status code checks and when constructing the FirebaseError. To improve type safety and prevent potential runtime issues, it's safer to ensure that status is a number.

Suggested change
const status = err?.context?.response?.statusCode || err?.status;
const code = err?.context?.response?.statusCode || err?.status;
const status = typeof code === "number" ? code : undefined;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error paths feeding these handlers already give us numeric status codes: responseToError sets statusCode as a number, gax errors use numeric code, and FirebaseError stores a numeric status (default 500). If a strange upstream ever handed us a string like "RESOURCE_EXHAUSTED", the 429 check would simply skip the quota branch and the FirebaseError would carry that string, but it wouldn’t change retry behavior because the executor’s parseErrorCode still looks for numeric codes.

// Sniff for runtime validation errors and log a more user-friendly warning.
if (err?.message?.includes("Runtime validation errors")) {
const capturedMessage = captureRuntimeValidationError(err.message);
Expand All @@ -238,7 +239,7 @@ function functionsOpLogReject(func: InputCloudFunction, type: string, err: any):
);
} else {
utils.logLabeledWarning("functions", `${err?.message}`);
if (err?.context?.response?.statusCode === 429) {
if (status === 429) {
utils.logLabeledWarning(
"functions",
`Got "Quota Exceeded" error while trying to ${type} ${func.name}. Waiting to retry...`,
Expand All @@ -261,7 +262,7 @@ function functionsOpLogReject(func: InputCloudFunction, type: string, err: any):
}
throw new FirebaseError(`Failed to ${type} function ${func.name}`, {
original: err,
status: err?.context?.response?.statusCode,
status,
context: { function: func.name },
});
}
Expand Down