Skip to content

Commit 97e3dec

Browse files
committed
clean up GitHubClient
1 parent 359b48a commit 97e3dec

File tree

1 file changed

+41
-55
lines changed

1 file changed

+41
-55
lines changed

src/github/client.ts

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ export class GitHubClient {
6161
}
6262
}
6363

64-
private async makeRequest(url: string, options: any): Promise<any> {
65-
const headers = await this.getAuthHeaders();
66-
67-
// Add Content-Type for requests with body
64+
private addContentTypeHeader(headers: Record<string, string>, options: any): void {
6865
if (options.body) {
6966
headers['Content-Type'] = 'application/json';
7067
}
68+
}
69+
70+
private async makeRequest(url: string, options: any): Promise<any> {
71+
const headers = await this.getAuthHeaders();
72+
this.addContentTypeHeader(headers, options);
7173

7274
const response = await fetch(url, {
7375
...options,
@@ -81,11 +83,7 @@ export class GitHubClient {
8183
if (response.status === 401 && this.installationId) {
8284
invalidateTokenCache(this.installationId);
8385
const retryHeaders = await this.getAuthHeaders();
84-
85-
// Add Content-Type for requests with body
86-
if (options.body) {
87-
retryHeaders['Content-Type'] = 'application/json';
88-
}
86+
this.addContentTypeHeader(retryHeaders, options);
8987

9088
const retryResponse = await fetch(url, {
9189
...options,
@@ -100,6 +98,26 @@ export class GitHubClient {
10098
return response;
10199
}
102100

101+
private async handleResponse(response: Response, expectJson = true): Promise<any> {
102+
if (!response.ok) {
103+
const errorText = await response.text();
104+
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
105+
}
106+
return expectJson ? await response.json() : await response.text();
107+
}
108+
109+
private async checkResponseError(response: Response, context?: string): Promise<void> {
110+
if (!response.ok) {
111+
const errorText = await response.text();
112+
const prefix = context ? `${context}: ` : 'GitHub API error: ';
113+
throw new Error(`${prefix}${response.status} ${response.statusText} - ${errorText}`);
114+
}
115+
}
116+
117+
private buildRepoUrl(owner: string, repo: string, path = ''): string {
118+
return `${this.baseUrl}/repos/${owner}/${repo}${path ? `/${path}` : ''}`;
119+
}
120+
103121
async createCheckRun(
104122
owner: string,
105123
repo: string,
@@ -121,7 +139,7 @@ export class GitHubClient {
121139
}>;
122140
}
123141
): Promise<any> {
124-
const url = `${this.baseUrl}/repos/${owner}/${repo}/check-runs`;
142+
const url = this.buildRepoUrl(owner, repo, 'check-runs');
125143

126144
const payload = {
127145
name: options.name,
@@ -138,12 +156,7 @@ export class GitHubClient {
138156
body: JSON.stringify(payload),
139157
});
140158

141-
if (!response.ok) {
142-
const errorText = await response.text();
143-
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
144-
}
145-
146-
return await response.json();
159+
return await this.handleResponse(response);
147160
}
148161

149162
async updateCheckRun(
@@ -166,19 +179,14 @@ export class GitHubClient {
166179
}>;
167180
}
168181
): Promise<any> {
169-
const url = `${this.baseUrl}/repos/${owner}/${repo}/check-runs/${checkRunId}`;
182+
const url = this.buildRepoUrl(owner, repo, `check-runs/${checkRunId}`);
170183

171184
const response = await this.makeRequest(url, {
172185
method: 'PATCH',
173186
body: JSON.stringify(options),
174187
});
175188

176-
if (!response.ok) {
177-
const errorText = await response.text();
178-
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
179-
}
180-
181-
return await response.json();
189+
return await this.handleResponse(response);
182190
}
183191

184192

@@ -194,7 +202,7 @@ export class GitHubClient {
194202
body: string;
195203
}>
196204
): Promise<any> {
197-
const url = `${this.baseUrl}/repos/${owner}/${repo}/pulls/${prNumber}/reviews`;
205+
const url = this.buildRepoUrl(owner, repo, `pulls/${prNumber}/reviews`);
198206

199207
const payload: any = {
200208
body,
@@ -210,44 +218,29 @@ export class GitHubClient {
210218
body: JSON.stringify(payload),
211219
});
212220

213-
if (!response.ok) {
214-
const errorText = await response.text();
215-
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
216-
}
217-
218-
return await response.json();
221+
return await this.handleResponse(response);
219222
}
220223

221224

222225
async getPRInfo(owner: string, repo: string, prNumber: number): Promise<any> {
223-
const url = `${this.baseUrl}/repos/${owner}/${repo}/pulls/${prNumber}`;
226+
const url = this.buildRepoUrl(owner, repo, `pulls/${prNumber}`);
224227

225228
const response = await this.makeRequest(url, {
226229
method: 'GET',
227230
});
228231

229-
if (!response.ok) {
230-
const errorText = await response.text();
231-
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
232-
}
233-
234-
return await response.json();
232+
return await this.handleResponse(response);
235233
}
236234

237235

238236
async getPRFiles(owner: string, repo: string, prNumber: number): Promise<any[]> {
239-
const url = `${this.baseUrl}/repos/${owner}/${repo}/pulls/${prNumber}/files`;
237+
const url = this.buildRepoUrl(owner, repo, `pulls/${prNumber}/files`);
240238

241239
const response = await this.makeRequest(url, {
242240
method: 'GET',
243241
});
244242

245-
if (!response.ok) {
246-
const errorText = await response.text();
247-
throw new Error(`GitHub API error: ${response.status} ${response.statusText} - ${errorText}`);
248-
}
249-
250-
return await response.json();
243+
return await this.handleResponse(response);
251244
}
252245

253246
async getFilteredPRDiff(
@@ -290,24 +283,17 @@ export class GitHubClient {
290283
// Fetch both issue comments (general discussion) and review comments (inline code comments)
291284
const [issueCommentsResponse, reviewCommentsResponse] = await Promise.all([
292285
// General PR discussion comments
293-
this.makeRequest(`${this.baseUrl}/repos/${owner}/${repo}/issues/${prNumber}/comments`, {
286+
this.makeRequest(this.buildRepoUrl(owner, repo, `issues/${prNumber}/comments`), {
294287
method: 'GET',
295288
}),
296289
// Inline code review comments
297-
this.makeRequest(`${this.baseUrl}/repos/${owner}/${repo}/pulls/${prNumber}/comments`, {
290+
this.makeRequest(this.buildRepoUrl(owner, repo, `pulls/${prNumber}/comments`), {
298291
method: 'GET',
299292
})
300293
]);
301294

302-
if (!issueCommentsResponse.ok) {
303-
const errorText = await issueCommentsResponse.text();
304-
throw new Error(`GitHub API error (issue comments): ${issueCommentsResponse.status} ${issueCommentsResponse.statusText} - ${errorText}`);
305-
}
306-
307-
if (!reviewCommentsResponse.ok) {
308-
const errorText = await reviewCommentsResponse.text();
309-
throw new Error(`GitHub API error (review comments): ${reviewCommentsResponse.status} ${reviewCommentsResponse.statusText} - ${errorText}`);
310-
}
295+
await this.checkResponseError(issueCommentsResponse, 'GitHub API error (issue comments)');
296+
await this.checkResponseError(reviewCommentsResponse, 'GitHub API error (review comments)');
311297

312298
const issueComments = await issueCommentsResponse.json();
313299
const reviewComments = await reviewCommentsResponse.json();

0 commit comments

Comments
 (0)