feat: add --ignore-not-found flag for delete command#6733
Conversation
vsukhin
left a comment
There was a problem hiding this comment.
hey, @dhimanAbhi
thank you for your contribution
but some of these resource will be deprecated very soon
testkube delete test
testkube delete testsuite
testkube delete executor
testkube delete template
testkube delete testsource
|
@vsukhin , Thanks for your review. As per your your suggestions, I will provide this flag for these resources only -
|
|
@greptile |
Greptile SummaryThis PR adds an Key findings:
Confidence Score: 2/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant CLI as testkube CLI (delete subcommand)
participant Transport as ProxyClient / DirectClient
participant API as Testkube API Server
User->>CLI: testkube delete testworkflow foo --ignore-not-found
CLI->>CLI: ignoreNotFound, _ = cmd.Flags().GetBool("ignore-not-found")
CLI->>Transport: client.DeleteTestWorkflow("foo")
Transport->>API: DELETE /v1/test-workflows/foo
API-->>Transport: HTTP 404 + problem JSON body
Note over Transport: responseError() parses problem JSON<br/>returns fmt.Errorf("api server problem: %s", detail)<br/>(plain string, no typed error wrapper)
Transport-->>CLI: error = "api/DELETE-... returned error: api server problem: ..."
CLI->>CLI: apiutils.IsNotFound(err)
Note over CLI: Checks: mongo.ErrNoDocuments? NO<br/>pgx.ErrNoRows? NO<br/>k8serrors.IsNotFound? NO (plain string)<br/>secretmanager.ErrNotFound? NO<br/>gRPC codes.NotFound? NO<br/>→ returns false
CLI->>User: ui.ExitOnError(...) — exits with non-zero ❌
Note over User,CLI: --ignore-not-found flag has no effect
|
vsukhin
left a comment
There was a problem hiding this comment.
hey @dhimanAbhi it looks good, you need just back merge main branch and fix a couple of greptile comments
|
@dhimanAbhi will you be able to fix this as requested above? 🙏 |
|
Hi @olensmar, I’ll address the review comments and update this PR by the end of the week. Thanks for the reminder. |
Signed-off-by: Abhishek Dhiman <abhi2002dhiman@gmail.com>
Signed-off-by: Abhishek Dhiman <abhi2002dhiman@gmail.com>
4ea86e1 to
3e29773
Compare
|
@greptile |
| if ignoreNotFound && apiutils.IsNotFound(err) { | ||
| ui.Info("Testworkflow '" + name + "' not found, but ignoring since --ignore-not-found was passed") | ||
| ui.SuccessAndExit("Operation completed") | ||
| } |
There was a problem hiding this comment.
apiutils.IsNotFound won't detect HTTP client errors
apiutils.IsNotFound checks for mongo.ErrNoDocuments, pgx.ErrNoRows, k8serrors.IsNotFound, secretmanager.ErrNotFound, and gRPC codes.NotFound — it is designed for server-side error detection.
However, the CLI clients (ProxyClient, DirectClient) return plain-string formatted errors for 404 responses:
- Proxy client:
fmt.Errorf("api server problem: %s", pr.Detail)(no%w, no typed error wrapping) - Direct client:
fmt.Errorf("problem: %+v", pr.Detail)(same)
Neither of these carries a wrapped typed error that the checks in apiutils.IsNotFound can detect. Consequently, apiutils.IsNotFound(err) will always return false for errors coming from the HTTP API clients, making --ignore-not-found a functional no-op — the error will still be passed to ui.ExitOnError.
The same issue affects every other site in this PR where apiutils.IsNotFound is used (lines 32–35 in this file, and corresponding locations in testworkflowtemplates/delete.go, webhooks/delete.go, webhooktemplates/delete.go).
A common workaround used in similar CLI tools is a string-based check, or adding a typed ErrNotFound sentinel in the client package that the transport layers wrap their 404 errors into. For example, a minimal string-based helper in the client package:
func IsNotFound(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "not found") || strings.Contains(msg, "404")
}This approach is fragile but consistent with how the existing proxy/direct client surfaces errors. Ideally a typed sentinel error should be introduced in the transport layer.
| if ignoreNotFound && apiutils.IsNotFound(err) { | ||
| ui.Info("Testworkflow not found for matching selector '" + selector + "', but ignoring since --ignore-not-found was passed") | ||
| ui.SuccessAndExit("Operation completed") | ||
| } |
There was a problem hiding this comment.
--ignore-not-found with selector never exits the function on ignore
When the ignoreNotFound check fires and calls ui.SuccessAndExit, control never reaches return (line 46). The ui.SuccessAndExit call does call os.Exit(0), so it terminates the process. However, this creates a subtle inconsistency: for the selector path the function uses return after the success/error pair, while the ignore path relies on os.Exit. This is consistent with the surrounding pattern but worth noting that the ignored-not-found path in the selector branch also skips the return statement on line 45, which is fine here because SuccessAndExit exits the process — but a future refactor that replaces SuccessAndExit with a non-exiting function would introduce a bug.
|
hey @dhimanAbhi please check above feedback |
|
hey @dhimanAbhi, will you be able to check it or do yo need our help? |
9aef050
into
kubeshop:dhimanAbhi/feat/add-ignore-not-found-flag
Pull request description
This PR introduces the
--ignore-not-foundflag to the testkube delete command. When enabled, this flag suppresses the error and non-zero exit code if the specified resource is does not exist.This improves usability in scripting and CI/CD environments by preventing unnecessary command failures when attempting to delete non-existent resources as descrinbed in #2304
Changes
testkube delete testtestkube delete testsuitetestkube delete testworkflowtestkube delete executortestkube delete templatetestkube delete testsourcetestkube delete webhooktestkube delete webhooktemplatetestkube delete testworkflowtemplateProof Manifests
Before
After