Skip to content

Handle OpenAPI spec fetch failures#57

Merged
R-Lawton merged 2 commits into
mainfrom
handle-openapi-fetching-errors
May 19, 2026
Merged

Handle OpenAPI spec fetch failures#57
R-Lawton merged 2 commits into
mainfrom
handle-openapi-fetching-errors

Conversation

@eguzki
Copy link
Copy Markdown
Contributor

@eguzki eguzki commented May 18, 2026

What

Fixed the issue where the APIProduct controller was reporting OpenAPI spec fetch failures as reconciliation errors

Why

When the controller fails to fetch the OpenAPI spec due to network errors (e.g., DNS lookup failures), it was returning a regular error which caused the reconciliation to fail and logged "Reconciler error" messages. This made it appear as a controller bug rather than a transient issue with the external resource.

Now, network errors and other fetch failures are gracefully handled and reported in the resource's status conditions instead, following Kubernetes best practices for reporting resource state.

How

Modified the openAPIStatus() function in apiproduct_controller.go to return OpenAPISpecErr for all fetch failures instead of regular errors:

  • Request creation errors → RequestCreationFailed reason
  • Network errors and HTTP error codes → FetchFailed reason
  • Response body read errors → ReadFailed reason

The error details are reflected in the OpenAPISpecReady status condition, and the status.openapi field contains an empty content.

Verification

Prerequisites

  • Local environment set up with make local-setup
  1. Create APIProduct with unreachable OpenAPI URL:
kubectl apply -f - <<EOF
apiVersion: devportal.kuadrant.io/v1alpha1
kind: APIProduct
metadata:
  name: test-apiproduct
  namespace: gamestore
spec:
  displayName: "Test API Product"
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: gamestore
  approvalMode: manual
  publishStatus: Published
  documentation:
    openAPISpecURL: https://api2.example.com/spec.yaml
EOF
  1. Verify no reconciler errors in controller logs:
kubectl logs -n developer-portal-controller-system deployment/developer-portal-controller-controller-manager | grep "Reconciler error"

Expected: No "Reconciler error" entries related to OpenAPI fetch

  1. Check APIProduct status condition:
kubectl get apiproduct test-apiproduct -n gamestore -o jsonpath='{.status.conditions[?(@.type=="OpenAPISpecReady")]}{"\n"}'

Expected output:

{
  "lastTransitionTime": "2026-05-18T20:36:23Z",
  "message": "failed to fetch OpenAPI spec from https://api2.example.com/spec.yaml: dial tcp: lookup api2.example.com on 10.96.0.10:53: server misbehaving",
  "reason": "FetchFailed",
  "status": "False",
  "type": "OpenAPISpecReady"
}
  1. Test recovery - update to valid URL:
kubectl patch apiproduct -n gamestore test-apiproduct --type=merge -p '{"spec":{"documentation":{"openAPISpecURL":"https://petstore3.swagger.io/api/v3/openapi.json"}}}'

Wait for reconciliation, then check:

kubectl get apiproduct test-apiproduct -n gamestore -o jsonpath='{.status.conditions[?(@.type=="OpenAPISpecReady")]}{"\n"}' | jq

Expected:

{
  "message": "OpenAPI spec was successfully fetched",
  "reason": "SpecFetched",
  "status": "True",
  "type": "OpenAPISpecReady"
}
  1. Cleanup:
make kind-delete-cluster

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Warning

Rate limit exceeded

@eguzki has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 36 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ac87d549-c4c2-4a6c-a8b0-d3afa169e95e

📥 Commits

Reviewing files that changed from the base of the PR and between aac5aea and 29c419e.

📒 Files selected for processing (2)
  • internal/controller/apiproduct_controller.go
  • internal/controller/apiproduct_controller_openapi_error_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch handle-openapi-fetching-errors

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@eguzki eguzki marked this pull request as ready for review May 18, 2026 21:07
@eguzki eguzki requested a review from R-Lawton May 18, 2026 21:08
@eguzki eguzki added this to Kuadrant May 18, 2026
@eguzki eguzki moved this to Ready For Review in Kuadrant May 18, 2026
@R-Lawton
Copy link
Copy Markdown
Contributor

👀

}

// Only fetch if spec has changed (generation mismatch) or env var changed
if apiProductObj.Status.OpenAPI != nil && apiProductObj.Generation == apiProductObj.Status.ObservedGeneration && apiProductObj.Status.OpenAPI.MaxSizeUsed == r.OpenAPISpecMaxSize {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

With this check and the new changes, were introducing the same error being showed everytime becuase the check doesn't pass, the status won't update, the same with generation and openapi size, Does that make sense? The new status doesnt get reconciled to break the loop

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes perfect sense.

I'm going to step back and take a broader view of the issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Created issue to address this #59

In the meantime, let's at least partially fix the issue where APIProduct status isn't reconciled when OpenAPI spec fetching fails.

@eguzki eguzki closed this May 19, 2026
@github-project-automation github-project-automation Bot moved this from Ready For Review to Done in Kuadrant May 19, 2026
@eguzki eguzki reopened this May 19, 2026
eguzki added 2 commits May 19, 2026 17:17
… spec fetch failures as reconciliation errors

Signed-off-by: Eguzki Astiz Lezaun <eastizle@redhat.com>
… change

Signed-off-by: Eguzki Astiz Lezaun <eastizle@redhat.com>
@eguzki eguzki force-pushed the handle-openapi-fetching-errors branch from a4f2081 to 29c419e Compare May 19, 2026 15:23
Copy link
Copy Markdown
Contributor

@R-Lawton R-Lawton left a comment

Choose a reason for hiding this comment

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

lgtm

@R-Lawton R-Lawton merged commit f294f17 into main May 19, 2026
18 checks passed
@R-Lawton R-Lawton deleted the handle-openapi-fetching-errors branch May 19, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants