Skip to content

feat: Allow partial success results - #400

Open
nurof3n wants to merge 1 commit into
prod-stagingfrom
nurof3n/partial-results
Open

feat: Allow partial success results#400
nurof3n wants to merge 1 commit into
prod-stagingfrom
nurof3n/partial-results

Conversation

@nurof3n

@nurof3n nurof3n commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

To be merged after #388
Closes TOOL-1048

@nurof3n
nurof3n requested a review from jedevc July 6, 2026 12:50
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch from 91aa4ef to e0a2d5b Compare July 6, 2026 12:52
@nurof3n nurof3n changed the title fix(volume): Allow GET to show more than expected results feat: Allow partial success results Jul 6, 2026
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch 3 times, most recently from 67276b3 to 1d4c4d4 Compare July 6, 2026 13:07
@jedevc

jedevc commented Jul 6, 2026

Copy link
Copy Markdown
Member

Ho hum. Can I get an explanation of what this one is for? 馃 It's not immediately obvious to me sorry!

@nurof3n

nurof3n commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Ho hum. Can I get an explanation of what this one is for? 馃 It's not immediately obvious to me sorry!

@jedevc Yup, so the router can return a 207 on listing or bulk requests when some of the metros returned errors, and it would contain both the results for successful calls and the errors for the others.
And I needed a way to show the error in the CLI and also show the listing output.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the CLI鈥檚 multi-metro list/get/delete operations to allow returning partial results when the API returns both a response payload and an error (or when only some items succeed). It introduces shared helpers in internal/cmd/util.go and wires them into several resource commands (instances, volumes, templates, certificates, service groups), aligning with TOOL-1048 and the follow-up to PR #388.

Changes:

  • Add shared partial-success helpers and a PartialResult error type to preserve successful items while still surfacing failures.
  • Update list/get handlers across multiple resources to continue processing response payloads even when an API error is present (when data exists).
  • Update delete handlers to detect partial deletions and return structured partial failures when possible.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/cmd/util.go Adds partial-success helpers (listGetOpError, deleteOpError), PartialResult, and error-combining utilities.
internal/cmd/instances.go Uses partial-success logic for list/get and returns partial delete results when some instances delete successfully.
internal/cmd/instance_templates.go Uses partial-success logic for template instance list/get/delete operations.
internal/cmd/volumes.go Uses partial-success logic for volume list/get and returns partial delete results when possible.
internal/cmd/volume_templates.go Uses partial-success logic for template volume list/get/delete operations.
internal/cmd/certificates.go Uses partial-success logic for certificate list/get and returns partial delete results when possible.
internal/cmd/services.go Uses partial-success logic for service group list/get; delete path attempts partial handling but currently has dead/unreachable logic.

馃挕 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/cmd/services.go Outdated
Comment thread internal/cmd/instances.go Outdated
Comment thread internal/cmd/instances.go Outdated
Comment thread internal/cmd/util.go Outdated
Comment thread internal/cmd/util.go Outdated
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch from 48a0314 to 7aece91 Compare July 8, 2026 10:13
@jedevc

jedevc commented Jul 8, 2026

Copy link
Copy Markdown
Member

Ho hum. Can I get an explanation of what this one is for? 馃 It's not immediately obvious to me sorry!

@jedevc Yup, so the router can return a 207 on listing or bulk requests when some of the metros returned errors, and it would contain both the results for successful calls and the errors for the others. And I needed a way to show the error in the CLI and also show the listing output.

Makes sense.

The bit that I don't get is the new helpers in utils.go. Why listGetOpError and similar? IMO, if the response has a partial-success (i.e. resp.Status == "partial_success" and status is 207), we should never abort processing. We should return both all the errors and all the successful responses. It feels like it's a bit overcomplicated but maybe I'm missing something.

Comment thread internal/cmd/instances.go Outdated
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch 2 times, most recently from eb97ef3 to c82a922 Compare August 3, 2026 13:23
@nurof3n

nurof3n commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@jedevc My bad, I simplified it and now we don't abort processing on partial success.
I also added some tests

@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch from c82a922 to 3d464ff Compare August 3, 2026 13:27
@nurof3n
nurof3n requested a review from jedevc August 3, 2026 13:36
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch from 3d464ff to 5c8e9aa Compare August 3, 2026 13:49
The router can answer a listing or a bulk request with a 207, carrying
both the results from the metros that succeeded and the errors from the
ones that did not. Abort on such a response and the successful half is
thrown away, so nothing is printed at all.

Never stop processing a response: collect whatever data came back and
join it with the errors, letting the callers decide. The commands
already print partial results before returning the error, so this is
mostly a matter of not discarding them on the way up.

Not-found is the exception: the group helpers already report the refs
that were missing, so ignoreNotFound() drops it on ref-based operations
to avoid reporting it twice. A listing has no refs to fall back on, so
it keeps reporting the error itself.

The lookups that surround a mutation only exist to display it, so a
partial lookup there is warned about rather than turned into a failure.
Waiting is not a mutation: the conditions can only be evaluated against
the resources that were looked up, so an incomplete lookup keeps the
wait polling instead of letting it succeed early.

Signed-off-by: Alex-Andrei Cioc <andrei.cioc@unikraft.io>
@nurof3n
nurof3n force-pushed the nurof3n/partial-results branch from 5c8e9aa to cdb4605 Compare August 3, 2026 13:51

@jedevc jedevc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, this is super neat. I like this a lot 馃帀

Small comments, good finds all around.

Comment on lines 124 to 126
if err != nil {
errs = append(errs, err)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, because errors.Join ignores nil errors, we can simplify this:

Suggested change
errs = append(errs, err)

Keeps this block nice and small.

Comment thread internal/cmd/instances.go
Comment on lines +1250 to +1252
if err != nil {
log.G(ctx).Warn().Err(err).Msg("instance created with partial lookup errors")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can this happen? I'm not sure I'd know what to do if I was greeted with this error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants