From 14be42ea96a88f18fa0437f62806abdbb8ea794c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:48:24 +0000 Subject: [PATCH 1/2] Initial plan for issue From eb2e4701ef7f11ce8091d838d5b68545445dcf05 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:02:29 +0000 Subject: [PATCH 2/2] Fix environment variables validation schema to handle error responses Co-authored-by: larp0 <204380501+larp0@users.noreply.github.com> --- packages/cli-v3/src/commands/deploy.ts | 12 +++++ packages/core/src/v3/schemas/api.ts | 12 +++-- .../test/environmentVariableResponse.test.ts | 53 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 packages/core/test/environmentVariableResponse.test.ts diff --git a/packages/cli-v3/src/commands/deploy.ts b/packages/cli-v3/src/commands/deploy.ts index 5c7304eff3..09f66c2fcd 100644 --- a/packages/cli-v3/src/commands/deploy.ts +++ b/packages/cli-v3/src/commands/deploy.ts @@ -392,6 +392,18 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) { "", $spinner ); + } else if ("error" in uploadResult.data) { + // Server returned 200 but with error in body + await failDeploy( + projectClient.client, + deployment, + { + name: "SyncEnvVarsError", + message: `Failed to sync ${numberOfEnvVars} env ${vars} with the server: ${uploadResult.data.error}`, + }, + "", + $spinner + ); } else { $spinner.stop(`Successfully synced ${numberOfEnvVars} env ${vars} with the server`); } diff --git a/packages/core/src/v3/schemas/api.ts b/packages/core/src/v3/schemas/api.ts index b8819347bf..680be03f48 100644 --- a/packages/core/src/v3/schemas/api.ts +++ b/packages/core/src/v3/schemas/api.ts @@ -813,9 +813,15 @@ export type ImportEnvironmentVariablesRequestBody = z.infer< typeof ImportEnvironmentVariablesRequestBody >; -export const EnvironmentVariableResponseBody = z.object({ - success: z.boolean(), -}); +export const EnvironmentVariableResponseBody = z.union([ + z.object({ + success: z.literal(true), + }), + z.object({ + error: z.string(), + variableErrors: z.array(z.any()).optional(), + }), +]); export type EnvironmentVariableResponseBody = z.infer; diff --git a/packages/core/test/environmentVariableResponse.test.ts b/packages/core/test/environmentVariableResponse.test.ts new file mode 100644 index 0000000000..4107373ada --- /dev/null +++ b/packages/core/test/environmentVariableResponse.test.ts @@ -0,0 +1,53 @@ +import { EnvironmentVariableResponseBody } from "../src/v3/schemas/api.js"; + +describe("EnvironmentVariableResponseBody schema", () => { + it("should accept success response", () => { + const successResponse = { success: true }; + const result = EnvironmentVariableResponseBody.safeParse(successResponse); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data).toEqual({ success: true }); + } + }); + + it("should accept error response with error field", () => { + const errorResponse = { error: "Something went wrong" }; + const result = EnvironmentVariableResponseBody.safeParse(errorResponse); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data).toEqual({ error: "Something went wrong" }); + } + }); + + it("should accept error response with error and variableErrors fields", () => { + const errorResponse = { + error: "Variable validation failed", + variableErrors: ["Invalid variable name", "Value too long"] + }; + const result = EnvironmentVariableResponseBody.safeParse(errorResponse); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data).toEqual({ + error: "Variable validation failed", + variableErrors: ["Invalid variable name", "Value too long"] + }); + } + }); + + it("should reject response without success or error field", () => { + const invalidResponse = { something: "else" }; + const result = EnvironmentVariableResponseBody.safeParse(invalidResponse); + + expect(result.success).toBe(false); + }); + + it("should reject response with success: false", () => { + const invalidResponse = { success: false }; + const result = EnvironmentVariableResponseBody.safeParse(invalidResponse); + + expect(result.success).toBe(false); + }); +}); \ No newline at end of file