Make PR detail load resilient to per-endpoint 403; bump to 1.3
Build iOS App / Build .ipa and publish source (push) Successful in 23s
Build iOS App / Build .ipa and publish source (push) Successful in 23s
Opening a PR could fail the whole screen when any one detail sub-request returns 401/403 (e.g. a token scope the repo's Actions endpoint needs). Refactor load() so the PR fetch is the only fatal call; comments/reviews/ files/commits/runs each fail independently, are logged, and the rest still render. Also log actions/runs failures for visibility. Bump to 1.3.
This commit is contained in:
1 parent
58eb145717
commit
9e71b6a8b9
2 files changed
+26
-19
No files matched your search
@@ -41,23 +41,28 @@ final class PRDetailViewModel: ObservableObject {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
defer { isLoading = false }
|
||||
// Fetch each piece independently. A single sub-request returning 403
|
||||
// (e.g. a token scope the repo's Actions needs) must NOT wipe the whole
|
||||
// detail screen — catch it, log it, keep the rest. Only a failure to
|
||||
// load the PR itself is fatal.
|
||||
do {
|
||||
async let prT = client.pullRequest(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let commentsT = client.comments(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let reviewsT = client.reviews(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let filesT = client.changedFiles(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let commitsT = client.commits(owner: owner, repo: repo.name, number: prNumber)
|
||||
pr = try await prT
|
||||
comments = try await commentsT
|
||||
reviews = try await reviewsT
|
||||
files = try await filesT
|
||||
commits = try await commitsT
|
||||
// CI runs depend on the head SHA from the PR.
|
||||
if let sha = pr?.head?.sha, !sha.isEmpty {
|
||||
await loadRuns(client: client, sha: sha)
|
||||
}
|
||||
pr = try await client.pullRequest(owner: owner, repo: repo.name, number: prNumber)
|
||||
} catch {
|
||||
LogStore.shared.log(.error, "PR \(prNumber): load failed: \(error.localizedDescription)")
|
||||
errorMessage = error.localizedDescription
|
||||
return
|
||||
}
|
||||
async let commentsT = client.comments(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let reviewsT = client.reviews(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let filesT = client.changedFiles(owner: owner, repo: repo.name, number: prNumber)
|
||||
async let commitsT = client.commits(owner: owner, repo: repo.name, number: prNumber)
|
||||
comments = (try? await commentsT) ?? []
|
||||
reviews = (try? await reviewsT) ?? []
|
||||
files = (try? await filesT) ?? []
|
||||
commits = (try? await commitsT) ?? []
|
||||
// CI runs depend on the head SHA from the PR.
|
||||
if let sha = pr?.head?.sha, !sha.isEmpty {
|
||||
await loadRuns(client: client, sha: sha)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +78,9 @@ final class PRDetailViewModel: ObservableObject {
|
||||
jobs[run.id] = jobList
|
||||
}
|
||||
} catch {
|
||||
// CI is best-effort; don't fail the whole detail view.
|
||||
// CI is best-effort; don't fail the whole detail view, but log it so
|
||||
// a token-scope 403 on the Actions endpoint is visible.
|
||||
LogStore.shared.log(.warn, "PR \(prNumber): actions/runs failed: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user