Files
orca/src/main/github/issue-comment.ts
T
OrcaWinandOrcaWin 3b9c1d356d fix(i18n): code GitHub/GitLab operation failures for the renderer (#35689)
* fix(i18n): code GitHub/GitLab operation failures for the renderer

* fix(i18n): show coded failures in comment composers; exhaustive classification switches

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 22:18:41 -07:00

81 lines
2.6 KiB
TypeScript

import type { GitHubCommentResult, PRComment } from '../../shared/github/comment-types'
import type { IssueSourcePreference } from '../../shared/repo-types'
import type { LocalGitExecOptions, OwnerRepo } from './gh-utils'
import {
resolveGitHubRepoExecution,
resolveIssueGitHubApiRepositorySource
} from './github-api-repository'
import { acquire, classifyGhError, ghExecFileAsync, release } from './gh-utils'
import { codeHostFailure, classifiedFailure } from '../../shared/code-host-failure-copy'
// An explicit target keeps replies bound to the conversation; otherwise use the selected source.
export async function addIssueComment(
repoPath: string,
issueNumber: number,
body: string,
connectionId?: string | null,
ownerRepoOverride?: OwnerRepo | null,
localGitOptions: LocalGitExecOptions = {},
preference?: IssueSourcePreference
): Promise<GitHubCommentResult> {
const { ownerRepo, ghOptions } = await resolveGitHubRepoExecution(
repoPath,
ownerRepoOverride ??
(async () =>
(
await resolveIssueGitHubApiRepositorySource(
repoPath,
preference,
connectionId,
localGitOptions
)
).source),
connectionId,
localGitOptions
)
if (!ownerRepo) {
return codeHostFailure('github.repoUnresolved')
}
await acquire()
try {
const { stdout } = await ghExecFileAsync(
[
'api',
'-X',
'POST',
`repos/${ownerRepo.owner}/${ownerRepo.repo}/issues/${issueNumber}/comments`,
'--input',
'-'
],
{ ...ghOptions, stdin: JSON.stringify({ body }) }
)
const data = JSON.parse(stdout) as {
id?: number
node_id?: string | null
user: { login: string; avatar_url: string; type?: string } | null
body?: string
created_at?: string
html_url?: string
}
if (typeof data.id !== 'number' || !Number.isSafeInteger(data.id) || data.id < 1) {
return codeHostFailure('github.unexpectedResponse')
}
const comment: PRComment = {
id: data.id,
reactionSubjectId: data.node_id?.trim() || undefined,
author: data.user?.login ?? 'You',
authorAvatarUrl: data.user?.avatar_url ?? '',
body: data.body ?? body,
createdAt: data.created_at ?? new Date().toISOString(),
url: data.html_url ?? '',
isBot: data.user?.type === 'Bot'
}
return { ok: true, comment }
} catch (err) {
const stderr = err instanceof Error ? err.message : String(err)
return classifiedFailure(classifyGhError(stderr))
} finally {
release()
}
}