fix: Properly handle server errors on project pages#1792
Open
Bojun-Feng wants to merge 1 commit intolinuxfoundation:mainfrom
Open
fix: Properly handle server errors on project pages#1792Bojun-Feng wants to merge 1 commit intolinuxfoundation:mainfrom
Bojun-Feng wants to merge 1 commit intolinuxfoundation:mainfrom
Conversation
…project pages * Change `return createError()` to `throw createError()` in the project API handler so 500 errors are properly surfaced as HTTP errors instead of being treated as successful responses * Add `v-else-if="isError"` branch to show a proper error message when the project query fails * Guard the "not onboarded" message with `data &&` so it only displays when the API has returned valid data confirming the project is not onboarded * Change `retry: false` to `retry: 2` with a 1 second delay so transient backend failures are retried client-side Signed-off-by: Bojun Feng <bojundf@gmail.com>
5f5acdd to
1e19b1d
Compare
Author
|
Hi @mbani01, would you mind having a look when you have time? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix #1788
Fix sonic-net/SONiC#2271
When the backend has a transient error while serving a project page, the server API handler at
frontend/server/api/project/[slug]/index.tsusesreturn createError()instead ofthrow createError()in its catch block. In H3 v2, this causes the error object to be treated as a normal successful JSON response rather than an HTTP error.The error object
{message: "Internal server error", statusCode: 500}then gets:Since the error object has no
contributorCountororganizationCountproperties, the page shows "This project hasn't been onboarded to LFX Insights" for a valid project. The client never retries because the query status is "success" andretryis set tofalse.Evidence from browser console on an affected page:
Root Cause Report on Issue #1788
Root Cause Analysis: "This project hasn't been onboarded to LFX Insights"
Summary
The "not onboarded" error on valid project pages is caused by the server API handler returning error objects instead of throwing them. This causes transient backend failures to be treated as successful responses, cached, and served to all users.
Evidence
I was able to reproduce the issue and inspect the live client state using the browser console. The key finding is that the TanStack Query cache contains the project query with status "success", but the data is actually a 500 error object.
1. The server HTML and API are fine
A direct curl to the API returns correct data:
The dehydrated Nuxt state embedded in the HTML also has the correct data:
2. But the live query cache has an error object disguised as success
On the affected page, the TanStack Query cache tells a different story:
The query status is "success", but the actual data is a 500 error response. This is why the page gets permanently stuck — the client believes the query succeeded and never retries.
3. Why this happens:
return createError()vsthrow createError()The server API handler at
frontend/server/api/project/[slug]/index.tshas:When a Nuxt server handler returns a
createError()result instead of throwing it, the framework treats it as a normal successful response with the error object as the body. The HTTP status code is 200,$fetchresolves normally, and TanStack Query stores the error object as valid data with status "success".4. How this cascades into the permanent "not onboarded" state
The page component
[slug].vuechecks:Since the error object
{message: "Internal server error", statusCode: 500}has nocontributorCountororganizationCount, this evaluates tofalse, and the template renders the "not onboarded" message.Because the query status is "success" and
retryis set tofalse, the client never retries. ThestaleTimeof 5 minutes means it won't refetch even on re-render. And in production, the Nitro response cache (setup/caching.ts) caches/project/**responses for 1 hour in Redis, so a single transient Tinybird failure poisons the cache for all users.5. Why incognito always works
Incognito bypasses the browser cache. If the Nitro server-side cache has expired or wasn't affected by the transient error, the fresh SSR works correctly. The original reporter also noted that "the page always loads normally when I open it in incognito," which is consistent with this being a caching issue around transient errors.
Suggested Fix
The primary fix is changing
return createError(...)tothrow createError(...)in the catch block of the server handler, so that 500 errors are properly surfaced as HTTP errors rather than treated as successful responses:} catch (err: unknown) { if (err && typeof err === 'object' && 'statusCode' in err && err.statusCode === 404) { throw err; } console.error('Error fetching project:', err); - return createError({ statusCode: 500, statusMessage: 'Internal server error' }); + throw createError({ statusCode: 500, statusMessage: 'Internal server error' }); }Additionally, on the client side in
[slug].vue, guarding the "not onboarded" message to only display when the query has returned valid data (not an error object) would prevent this class of issue from showing a misleading message:And changing
retry: falsetoretry: 2would allow the client to recover from transient failures even when the SSR didn't cache a successful response.