From ba596376426331c21dc0ff8af1db9b6a4957c2ff Mon Sep 17 00:00:00 2001 From: ProgrammerIn-wonderland <3838shah@gmail.com> Date: Mon, 11 May 2026 16:40:47 -0400 Subject: [PATCH] Fix error reporting in puterjs. Add precheck for puterOutputPath --- .../drivers/ai-image/ImageGenerationDriver.ts | 36 ++++++++++++------- .../drivers/ai-video/VideoGenerationDriver.ts | 36 ++++++++++++------- src/puter-js/src/lib/utils.js | 4 +-- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/backend/drivers/ai-image/ImageGenerationDriver.ts b/src/backend/drivers/ai-image/ImageGenerationDriver.ts index b0415f716..b6a04fb09 100644 --- a/src/backend/drivers/ai-image/ImageGenerationDriver.ts +++ b/src/backend/drivers/ai-image/ImageGenerationDriver.ts @@ -121,6 +121,25 @@ export class ImageGenerationDriver extends PuterDriver { const puterOutputPath = args.puter_output_path; delete args.puter_output_path; + // Validate the output path early — before spending credits. + let resolvedOutputPath: string | undefined; + if (puterOutputPath) { + const username = actor.user?.username; + const userId = actor.user?.id; + if (!userId || !username) { + throw new HttpError( + 400, + 'User ID required for puter_output_path', + { legacyCode: 'bad_request' }, + ); + } + resolvedOutputPath = this.#resolveOutputPath( + puterOutputPath, + username, + ); + await this.#assertWriteAccess(actor, resolvedOutputPath); + } + let modelId = args.model?.trim().toLowerCase(); let intendedProvider = args.provider ?? (Context.get('driverName') as string | undefined); @@ -179,8 +198,8 @@ export class ImageGenerationDriver extends PuterDriver { provider: model.provider, }); - if (puterOutputPath) { - await this.#saveToFS(actor, result, puterOutputPath); + if (resolvedOutputPath) { + await this.#saveToFS(actor, result, resolvedOutputPath); } return result; @@ -350,18 +369,9 @@ export class ImageGenerationDriver extends PuterDriver { async #saveToFS( actor: Actor, result: string, - outputPath: string, + resolvedPath: string, ): Promise { - const userId = actor.user?.id; - const username = actor.user?.username; - if (!userId || !username) { - throw new HttpError(400, 'User ID required for puter_output_path', { - legacyCode: 'bad_request', - }); - } - - const resolvedPath = this.#resolveOutputPath(outputPath, username); - await this.#assertWriteAccess(actor, resolvedPath); + const userId = actor.user!.id!; let buffer: Buffer; let contentType: string; diff --git a/src/backend/drivers/ai-video/VideoGenerationDriver.ts b/src/backend/drivers/ai-video/VideoGenerationDriver.ts index 98ee9966b..a73ac264d 100644 --- a/src/backend/drivers/ai-video/VideoGenerationDriver.ts +++ b/src/backend/drivers/ai-video/VideoGenerationDriver.ts @@ -121,6 +121,25 @@ export class VideoGenerationDriver extends PuterDriver { const puterOutputPath = args.puter_output_path; delete args.puter_output_path; + // Validate the output path early — before spending credits. + let resolvedOutputPath: string | undefined; + if (puterOutputPath) { + const username = actor.user?.username; + const userId = actor.user?.id; + if (!userId || !username) { + throw new HttpError( + 400, + 'User ID required for puter_output_path', + { legacyCode: 'bad_request' }, + ); + } + resolvedOutputPath = this.#resolveOutputPath( + puterOutputPath, + username, + ); + await this.#assertWriteAccess(actor, resolvedOutputPath); + } + if (args.model) { args.model = args.model.trim().toLowerCase(); } @@ -209,8 +228,8 @@ export class VideoGenerationDriver extends PuterDriver { provider: model.provider, }); - if (puterOutputPath) { - return await this.#saveToFS(actor, result, puterOutputPath); + if (resolvedOutputPath) { + return await this.#saveToFS(actor, result, resolvedOutputPath); } return result; @@ -360,18 +379,9 @@ export class VideoGenerationDriver extends PuterDriver { async #saveToFS( actor: Actor, result: unknown, - outputPath: string, + resolvedPath: string, ): Promise { - const userId = actor.user?.id; - const username = actor.user?.username; - if (!userId || !username) { - throw new HttpError(400, 'User ID required for puter_output_path', { - legacyCode: 'bad_request', - }); - } - - const resolvedPath = this.#resolveOutputPath(outputPath, username); - await this.#assertWriteAccess(actor, resolvedPath); + const userId = actor.user!.id!; let buffer: Buffer; let contentType: string; diff --git a/src/puter-js/src/lib/utils.js b/src/puter-js/src/lib/utils.js index a1de6cda6..8bfdfbf73 100644 --- a/src/puter-js/src/lib/utils.js +++ b/src/puter-js/src/lib/utils.js @@ -521,7 +521,7 @@ async function driverCall_ ( } // HTTP Error - unauthorized - if ( response.status === 401 || resp?.code === 'token_auth_failed' ) { + if ( response.target.status === 401 || resp?.code === 'token_auth_failed' ) { if ( resp?.code === 'token_auth_failed' && puter.env === 'web' ) { try { puter.resetAuthToken(); @@ -543,7 +543,7 @@ async function driverCall_ ( return reject_func({ status: 401, message: 'Unauthorized' }); } // HTTP Error - other - else if ( response.status && response.status !== 200 ) { + else if ( response.target.status && response.target.status !== 200 ) { // if error callback is provided, call it error_cb(resp); // reject promise