From 8d19be486eb7d043981222fb4708767bc7cd058c Mon Sep 17 00:00:00 2001 From: Codeflash Bot Date: Wed, 21 Jan 2026 15:56:15 +0200 Subject: [PATCH 1/2] Enhance error handling for GitHub App installation checks in code context hash endpoints. Added specific exceptions for installation not found and installation errors, improving logging and user guidance for installation issues. --- js/cf-api/endpoints/code-context-hash.ts | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/js/cf-api/endpoints/code-context-hash.ts b/js/cf-api/endpoints/code-context-hash.ts index 7c52fc97e..652e56dc0 100644 --- a/js/cf-api/endpoints/code-context-hash.ts +++ b/js/cf-api/endpoints/code-context-hash.ts @@ -12,6 +12,8 @@ import { validationFailure, internalServerError, conflict, + githubInstallationNotFound, + githubInstallationError, } from "../exceptions/index.js" export async function is_code_being_optimized_again(req: Request, res: Response) { @@ -28,7 +30,19 @@ export async function is_code_being_optimized_again(req: Request, res: Response) } const octokit = await getInstallationOctokitByOwner(githubApp, owner, repo, userId) if (octokit instanceof Error) { - throw internalServerError(octokit.message) + const errorMessage = octokit.message + if (errorMessage.includes("not installed")) { + const installationLink = "https://github.com/apps/codeflash-ai/installations/select_target" + logger.warn("GitHub App not installed on repository", req, { + repo: `${owner}/${repo}`, + installationLink, + }) + throw githubInstallationNotFound( + `${owner}/${repo}. Please install the GitHub App at: ${installationLink}`, + ) + } else { + throw githubInstallationError(errorMessage) + } } // Check collaborator status with error handling @@ -164,7 +178,19 @@ export async function add_optimized_code_context(req: Request, res: Response) { const octokit = await getInstallationOctokitByOwner(githubApp, owner, repo, userId) if (octokit instanceof Error) { - throw internalServerError(octokit.message) + const errorMessage = octokit.message + if (errorMessage.includes("not installed")) { + const installationLink = "https://github.com/apps/codeflash-ai/installations/select_target" + logger.warn("GitHub App not installed on repository", req, { + repo: `${owner}/${repo}`, + installationLink, + }) + throw githubInstallationNotFound( + `${owner}/${repo}. Please install the GitHub App at: ${installationLink}`, + ) + } else { + throw githubInstallationError(errorMessage) + } } // Check collaborator status with error handling From 0b87fa0e1299577be3316f37bfa00b655d532f24 Mon Sep 17 00:00:00 2001 From: Codeflash Bot Date: Wed, 21 Jan 2026 16:04:13 +0200 Subject: [PATCH 2/2] Refactor GitHub App installation error handling in code context hash endpoints. Introduced a dedicated assertion function to streamline error validation and improve logging for installation issues. --- js/cf-api/endpoints/code-context-hash.ts | 61 ++++++++++++------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/js/cf-api/endpoints/code-context-hash.ts b/js/cf-api/endpoints/code-context-hash.ts index 652e56dc0..b70c36f27 100644 --- a/js/cf-api/endpoints/code-context-hash.ts +++ b/js/cf-api/endpoints/code-context-hash.ts @@ -1,5 +1,6 @@ import { prisma } from "@codeflash-ai/common" import { Request, Response } from "express" +import { Octokit } from "@octokit/core" import { githubApp } from "../github/github-app.js" import { getInstallationOctokitByOwner, isUserCollaborator } from "../github/github-utils.js" import { userNickname } from "../auth0-mgmt.js" @@ -16,6 +17,34 @@ import { githubInstallationError, } from "../exceptions/index.js" +const GITHUB_APP_INSTALL_LINK = "https://github.com/apps/codeflash-ai/installations/select_target" + +/** + * Validates the installation octokit result and throws appropriate errors if it's an Error. + * Uses TypeScript assertion to narrow the type to Octokit on success. + */ +function assertInstallationOctokit( + octokit: Octokit | Error, + owner: string, + repo: string, + req: Request, +): asserts octokit is Octokit { + if (!(octokit instanceof Error)) return + + const repoPath = `${owner}/${repo}` + const errorMessage = octokit.message + + if (errorMessage.includes("not installed")) { + logger.warn("GitHub App not installed on repository", req, { + repo: repoPath, + installationLink: GITHUB_APP_INSTALL_LINK, + }) + throw githubInstallationNotFound(`${repoPath}. Please install the GitHub App at: ${GITHUB_APP_INSTALL_LINK}`) + } else { + throw githubInstallationError(errorMessage) + } +} + export async function is_code_being_optimized_again(req: Request, res: Response) { try { const { owner, repo, pr_number, code_contexts } = req.body @@ -29,21 +58,7 @@ export async function is_code_being_optimized_again(req: Request, res: Response) throw unauthorized("") } const octokit = await getInstallationOctokitByOwner(githubApp, owner, repo, userId) - if (octokit instanceof Error) { - const errorMessage = octokit.message - if (errorMessage.includes("not installed")) { - const installationLink = "https://github.com/apps/codeflash-ai/installations/select_target" - logger.warn("GitHub App not installed on repository", req, { - repo: `${owner}/${repo}`, - installationLink, - }) - throw githubInstallationNotFound( - `${owner}/${repo}. Please install the GitHub App at: ${installationLink}`, - ) - } else { - throw githubInstallationError(errorMessage) - } - } + assertInstallationOctokit(octokit, owner, repo, req) // Check collaborator status with error handling try { @@ -177,21 +192,7 @@ export async function add_optimized_code_context(req: Request, res: Response) { } const octokit = await getInstallationOctokitByOwner(githubApp, owner, repo, userId) - if (octokit instanceof Error) { - const errorMessage = octokit.message - if (errorMessage.includes("not installed")) { - const installationLink = "https://github.com/apps/codeflash-ai/installations/select_target" - logger.warn("GitHub App not installed on repository", req, { - repo: `${owner}/${repo}`, - installationLink, - }) - throw githubInstallationNotFound( - `${owner}/${repo}. Please install the GitHub App at: ${installationLink}`, - ) - } else { - throw githubInstallationError(errorMessage) - } - } + assertInstallationOctokit(octokit, owner, repo, req) // Check collaborator status with error handling try {