优化git处理
This commit is contained in:
@@ -91,8 +91,10 @@ fn classify_remote_git_error(operation: &str, stderr: &[u8]) -> AppCommandError
|
|||||||
|| lower.contains("could not read username")
|
|| lower.contains("could not read username")
|
||||||
|| lower.contains("could not read password")
|
|| lower.contains("could not read password")
|
||||||
|| lower.contains("logon failed")
|
|| lower.contains("logon failed")
|
||||||
|| lower.contains("401")
|
|| lower.contains("terminal prompts disabled")
|
||||||
|| lower.contains("403")
|
|| lower.contains("the requested url returned error: 401")
|
||||||
|
|| lower.contains("the requested url returned error: 403")
|
||||||
|
|| lower.contains("http basic: access denied")
|
||||||
{
|
{
|
||||||
return AppCommandError::authentication_failed(format!(
|
return AppCommandError::authentication_failed(format!(
|
||||||
"git {operation}: authentication failed. Configure a GitHub account in Settings → Version Control."
|
"git {operation}: authentication failed. Configure a GitHub account in Settings → Version Control."
|
||||||
@@ -565,6 +567,12 @@ fn classify_git_clone_error(stderr: &str) -> AppCommandError {
|
|||||||
|
|
||||||
if normalized.contains("authentication failed")
|
if normalized.contains("authentication failed")
|
||||||
|| normalized.contains("could not read username")
|
|| normalized.contains("could not read username")
|
||||||
|
|| normalized.contains("could not read password")
|
||||||
|
|| normalized.contains("logon failed")
|
||||||
|
|| normalized.contains("terminal prompts disabled")
|
||||||
|
|| normalized.contains("the requested url returned error: 401")
|
||||||
|
|| normalized.contains("the requested url returned error: 403")
|
||||||
|
|| normalized.contains("http basic: access denied")
|
||||||
|| normalized.contains("permission denied (publickey)")
|
|| normalized.contains("permission denied (publickey)")
|
||||||
{
|
{
|
||||||
return AppCommandError::authentication_failed(
|
return AppCommandError::authentication_failed(
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ export function GitCredentialProvider({
|
|||||||
operation: (credentials?: GitCredentials) => Promise<T>,
|
operation: (credentials?: GitCredentials) => Promise<T>,
|
||||||
hint: GitRemoteHint
|
hint: GitRemoteHint
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
|
// First attempt — no explicit credentials
|
||||||
try {
|
try {
|
||||||
return await operation()
|
return await operation()
|
||||||
} catch (firstError) {
|
} catch (firstError) {
|
||||||
@@ -336,13 +337,6 @@ export function GitCredentialProvider({
|
|||||||
? "github"
|
? "github"
|
||||||
: "generic"
|
: "generic"
|
||||||
|
|
||||||
// Show credential dialog
|
|
||||||
const creds = await requestCredentials(dialogMode, host)
|
|
||||||
if (!creds) {
|
|
||||||
setOpen(false)
|
|
||||||
throw firstError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: save credentials after successful operation
|
// Helper: save credentials after successful operation
|
||||||
const maybeSave = async (c: GitCredentials) => {
|
const maybeSave = async (c: GitCredentials) => {
|
||||||
if (modeRef.current === "generic" && saveCredentialsRef.current) {
|
if (modeRef.current === "generic" && saveCredentialsRef.current) {
|
||||||
@@ -351,15 +345,31 @@ export function GitCredentialProvider({
|
|||||||
// GitHub mode saves during handleGitHubSubmit, no extra work needed
|
// GitHub mode saves during handleGitHubSubmit, no extra work needed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry with credentials
|
// Show credential dialog for the first time
|
||||||
try {
|
let creds = await requestCredentials(dialogMode, host)
|
||||||
const result = await operation(creds)
|
if (!creds) {
|
||||||
await maybeSave(creds)
|
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
return result
|
throw firstError
|
||||||
} catch (retryError) {
|
}
|
||||||
setSubmitting(false)
|
|
||||||
if (isAuthError(retryError)) {
|
// Retry loop — keep trying until success or user cancels
|
||||||
|
let lastError: unknown = firstError
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const result = await operation(creds)
|
||||||
|
await maybeSave(creds)
|
||||||
|
setOpen(false)
|
||||||
|
return result
|
||||||
|
} catch (retryError) {
|
||||||
|
lastError = retryError
|
||||||
|
if (!isAuthError(retryError)) {
|
||||||
|
// Non-auth error — stop retrying
|
||||||
|
setOpen(false)
|
||||||
|
throw retryError
|
||||||
|
}
|
||||||
|
// Auth error — show error and let user try again
|
||||||
|
setSubmitting(false)
|
||||||
setError(t("invalidCredentials"))
|
setError(t("invalidCredentials"))
|
||||||
const retryCreds = await new Promise<GitCredentials | null>(
|
const retryCreds = await new Promise<GitCredentials | null>(
|
||||||
(resolve) => {
|
(resolve) => {
|
||||||
@@ -368,20 +378,10 @@ export function GitCredentialProvider({
|
|||||||
)
|
)
|
||||||
if (!retryCreds) {
|
if (!retryCreds) {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
throw retryError
|
throw lastError
|
||||||
}
|
|
||||||
try {
|
|
||||||
const result = await operation(retryCreds)
|
|
||||||
await maybeSave(retryCreds)
|
|
||||||
setOpen(false)
|
|
||||||
return result
|
|
||||||
} catch (thirdError) {
|
|
||||||
setOpen(false)
|
|
||||||
throw thirdError
|
|
||||||
}
|
}
|
||||||
|
creds = retryCreds
|
||||||
}
|
}
|
||||||
setOpen(false)
|
|
||||||
throw retryError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user