fix: refresh issue/PR detail after a partial edit failure (#50)

IssueEditView and PullRequestEditView save by running several API calls in
sequence (replaceLabels, editIssue, editPullRequest, requestReviewers,
removeReviewers). Forgejo has no transaction, so if a later call fails the
earlier ones stay committed, yet the catch block only showed an error and never
fired onSaved, leaving the detail view with stale data.

On failure, re-fetch the issue/PR and push the authoritative server state via
onSaved (without dismissing, so the user can retry) before surfacing the error.
True rollback is not possible against the REST API; reflecting the real
committed state is the correct remedy.

Reviewed-on: https://codeberg.org/secana/Forji/pulls/66
This commit is contained in:
Stefan Hausotte 2026-06-04 14:07:53 +02:00 committed by secana
parent 8e7f99b6e3
commit d95ec8ddc5
2 changed files with 18 additions and 0 deletions

View file

@ -127,6 +127,14 @@ struct IssueEditView: View {
onSaved(updatedIssue)
dismiss()
} catch {
// The calls above run in sequence with no transaction, so an earlier
// one may already be committed on the server. Re-fetch the issue and
// push the authoritative state to the detail view so it does not show
// stale data, then surface the error and keep the sheet open to retry.
if let refreshed = try? await issueService.fetchIssue(owner: owner, repo: repo, index: issue.number) {
NotificationCenter.default.post(name: .issuesDidChange, object: nil)
onSaved(refreshed)
}
errorMessage = error.localizedDescription
showError = true
}

View file

@ -173,6 +173,16 @@ struct PullRequestEditView: View {
onSaved(updatedPR)
dismiss()
} catch {
// The calls above run in sequence with no transaction, so an earlier
// one may already be committed on the server. Re-fetch the PR and push
// the authoritative state to the detail view so it does not show stale
// data, then surface the error and keep the sheet open to retry.
if let refreshed = try? await prService.fetchPullRequest(
owner: owner, repo: repo, index: pullRequest.number,
) {
NotificationCenter.default.post(name: .pullRequestsDidChange, object: nil)
onSaved(refreshed)
}
errorMessage = error.localizedDescription
showError = true
}