-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgit-errors.ts
More file actions
75 lines (66 loc) · 2.16 KB
/
Copy pathgit-errors.ts
File metadata and controls
75 lines (66 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* Git error classification — extracted so it can be tested independently
* of simple-git module mocks that other tests install.
*/
export class GitCloneError extends Error {
readonly url: string;
readonly isTimeout: boolean;
readonly isAuthError: boolean;
constructor(
message: string,
url: string,
isTimeout = false,
isAuthError = false,
) {
super(message);
this.name = 'GitCloneError';
this.url = url;
this.isTimeout = isTimeout;
this.isAuthError = isAuthError;
}
}
export function classifyError(
error: unknown,
url: string,
timeoutMs = 60_000,
): GitCloneError {
const errorMessage =
error instanceof Error ? error.message : String(error);
const isTimeout =
errorMessage.includes('block timeout') ||
errorMessage.includes('timed out');
const isAuthError =
errorMessage.includes('Authentication failed') ||
errorMessage.includes('could not read Username') ||
errorMessage.includes('Permission denied') ||
errorMessage.includes('Repository not found');
// HTTP 5xx from the remote can indicate auth/token issues (e.g., expired
// credential sent by Git Credential Manager) rather than a genuine server
// error. Treat it like an auth error so callers get actionable guidance.
const isServerError =
/returned error: 5\d\d/.test(errorMessage) ||
errorMessage.includes('Internal Server Error');
if (isTimeout) {
const timeoutSeconds = Math.round(timeoutMs / 1000);
return new GitCloneError(
`Clone timed out after ${timeoutSeconds}s for ${url}.\n Check your network connection and repository access.\n For SSH: ssh-add -l (to check loaded keys)\n For HTTPS: Check your git credentials`,
url,
true,
false,
);
}
if (isAuthError || isServerError) {
return new GitCloneError(
`Authentication failed for ${url}.\n For private repos, ensure you have access.\n For SSH: Check your keys with 'ssh -T git@github.com'\n For HTTPS: Configure git credentials or run 'gh auth setup-git'`,
url,
false,
true,
);
}
return new GitCloneError(
`Failed to clone ${url}: ${errorMessage}`,
url,
false,
false,
);
}