Skip to content

fix(graphql): handle partial failure errors gracefully with localized fallbacks (fixes #1626) - #2412

Merged
krushit1307 merged 1 commit into
krushit1307:mainfrom
Diwakar-odds:fix/issue-1626-graphql-partial-errors
Aug 4, 2026
Merged

fix(graphql): handle partial failure errors gracefully with localized fallbacks (fixes #1626)#2412
krushit1307 merged 1 commit into
krushit1307:mainfrom
Diwakar-odds:fix/issue-1626-graphql-partial-errors

Conversation

@Diwakar-odds

@Diwakar-odds Diwakar-odds commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Description

This pull request introduces centralized GraphQL partial failure handling. Instead of swallowing GraphQL errors into a pure success state (which caused components to blindly map over null values and crash to an Error Boundary), the shared fetchGraphQL utility now appropriately throws a custom GraphQLPartialError. Callers (such as useCursorEventsQuery and admin.users.tsx) now gracefully catch this error and render the available partial data with proper localized fallbacks.

Type of Change

  • New Feature
  • Bug Fix
  • Documentation Update
  • Refactor
  • Performance Improvement
  • Security Improvement
  • Other

Related Issue

Closes #1626

Testing

Describe the testing performed.

  • Tested locally
  • Existing functionality verified
  • No new warnings or errors

Comprehensive tests were added for the new fetchGraphQL client, validating it against partial successes, complete network errors, and standard GraphQL payloads. The test for useCursorEventsQuery was updated to explicitly mock and handle a partial GraphQL failure gracefully.

Screenshots

N/A

Checklist

  • Code follows project conventions
  • Documentation updated where required
  • No unnecessary files included
  • Changes have been tested
  • Ready for review

Summary by CodeRabbit

  • Bug Fixes
    • Improved GraphQL request handling for HTTP failures, malformed responses, and complete query errors.
    • Preserves and displays available profile and count data when responses contain partial results.
    • Shows a warning when partial data is available instead of failing the entire request.
    • Improved cursor-based event loading reliability and consistency across requests.

@github-actions github-actions Bot added bug Something isn't working ECSoC26 Elite Coders Summer Of Code'26 - Open Source Program frontend labels Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a shared GraphQL client with typed errors, partial-data handling, configurable requests, and OpenTelemetry reporting. The cursor-events hook re-exports it. The admin users route renders available profile data when GraphQL returns partial errors.

Changes

GraphQL partial-error handling

Layer / File(s) Summary
Shared GraphQL client and response contracts
src/lib/graphql-client.ts, src/lib/graphql-client.test.ts
Adds typed GraphQL responses, GraphQLPartialError, configurable POST requests, HTTP and response-level error handling, OpenTelemetry reporting, and isPartialNull tests.
Consumer integration and partial-data handling
src/hooks/useCursorEventsQuery.ts, src/hooks/useCursorEventsQuery.test.ts, src/routes/admin.users.tsx
Re-exports the shared client, updates fetch mocks, and handles partial profile data with warning feedback while preserving generic failure handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AdminUsers
  participant fetchGraphQL
  participant GraphQLAPI
  participant OpenTelemetry
  AdminUsers->>fetchGraphQL: Request profile data
  fetchGraphQL->>GraphQLAPI: POST GraphQL query
  GraphQLAPI-->>fetchGraphQL: Return data and optional errors
  fetchGraphQL->>OpenTelemetry: Record GraphQL errors
  fetchGraphQL-->>AdminUsers: Return data or GraphQLPartialError
  AdminUsers-->>AdminUsers: Render available data and show warning
Loading

Possibly related PRs

Suggested labels: backend, good-backend, good-pr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes centralized GraphQL partial-failure handling and localized fallbacks, matching the primary changes.
Linked Issues check ✅ Passed The changes preserve partial data, distinguish complete failures, add telemetry, support localized fallbacks, and test the GraphQL error paths for issue [#1626].
Out of Scope Changes check ✅ Passed All changed production files and tests support shared GraphQL error handling, partial-data rendering, telemetry, or related regression coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@Diwakar-odds

Copy link
Copy Markdown
Contributor Author

@krushit1307 The implementation for handling partial GraphQL errors is complete and ready for review! 🚀

Technical Analysis of Changes

  • Core Architecture Update: Introduced a centralized src/lib/graphql-client.ts that properly evaluates GraphQLResponse<TData> payloads. It separates complete network failures (throwing standard Error) from partial successes.
  • GraphQLPartialError Custom Type: Instead of swallowing the error array when partial data is returned, the client now throws a GraphQLPartialError. This forces callers to acknowledge the error while still providing access to the .data payload for graceful rendering.
  • Robust Telemetry: Integrated @opentelemetry/api within the client to ensure every partial failure logs standard graphql.partial_error telemetry (including operation hints and error paths) to the backend before exposing the partial data.
  • Component & Hook Updates: Replaced the inline fetching in useCursorEventsQuery with the shared client. Updated admin.users.tsx to handle GraphQLPartialError in its try/catch block, ensuring that partial user lists load cleanly without triggering a full page Error Boundary crash.
  • Test Coverage: Added comprehensive branch test coverage for the new utility (graphql-client.test.ts) and updated the React Query tests to simulate nested relation failures.

ECSoC26 Justification

This PR represents a Level 3 (Core/Arch/Perf) contribution because it directly modifies the foundational data-fetching pipeline and error-handling architecture across the frontend client. It addresses a core architectural flaw where a minor localized resolver timeout in the backend would cascade into a fatal TypeError page crash on the frontend. This change increases the overall resilience of the UI.

Please add the following labels if you agree:

  • ECSoC26
  • Level 3
  • good-backend or good-pr

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/graphql-client.ts`:
- Around line 35-38: Use one partial-response contract across the client, hook,
and tests: in src/lib/graphql-client.ts lines 35-38 retain GraphQLPartialError,
keep its `@throws` documentation accurate at lines 84-86, and throw
GraphQLPartialError with both json.errors and json.data at lines 116-122. Update
src/lib/graphql-client.test.ts lines 56-70 to assert the typed rejection and
both payloads. In src/hooks/useCursorEventsQuery.ts line 96, adapt
GraphQLPartialError by returning its data to React Query, and update
src/hooks/useCursorEventsQuery.test.ts lines 81-110 to verify partial-data
recovery through that adapter.

In `@src/routes/admin.users.tsx`:
- Around line 131-136: Update the GraphQLPartialError handling in the route’s
data-loading flow to track profiles and totalProfiles as nullable partial
fields, clearing each failed field instead of retaining prior state. Apply safe
replacements for missing fields, such as an empty profile list and a neutral
pagination total, and render section-specific fallbacks while preserving
successfully returned partial data.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5bbbb8bd-e02f-4da0-b52b-1928c5556d2a

📥 Commits

Reviewing files that changed from the base of the PR and between d50f99c and 9bd3ce7.

📒 Files selected for processing (5)
  • src/hooks/useCursorEventsQuery.test.ts
  • src/hooks/useCursorEventsQuery.ts
  • src/lib/graphql-client.test.ts
  • src/lib/graphql-client.ts
  • src/routes/admin.users.tsx

Comment thread src/lib/graphql-client.ts
Comment on lines +35 to +38
/**
* A custom error class carrying the partial `data` alongside the
* GraphQL `errors` array. Components can check
* `instanceof GraphQLPartialError` and decide to render partial UI.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use one partial-response contract across the client, hook, and tests.

The shared documentation requires GraphQLPartialError, but the implementation and tests use normal resolution. This prevents callers from receiving both partial data and error details.

  • src/lib/graphql-client.ts#L35-L38: retain the documented typed-error contract.
  • src/lib/graphql-client.ts#L84-L86: keep the @throws GraphQLPartialError contract accurate.
  • src/lib/graphql-client.ts#L116-L122: throw new GraphQLPartialError(json.errors, json.data).
  • src/lib/graphql-client.test.ts#L56-L70: assert the typed rejection and both stored payloads.
  • src/hooks/useCursorEventsQuery.ts#L96-L96: add an adapter that returns GraphQLPartialError.data for React Query.
  • src/hooks/useCursorEventsQuery.test.ts#L81-L110: test the adapter’s partial-data recovery instead of the shared client’s incorrect resolution behavior.
📍 Affects 4 files
  • src/lib/graphql-client.ts#L35-L38 (this comment)
  • src/lib/graphql-client.ts#L84-L86
  • src/lib/graphql-client.ts#L116-L122
  • src/lib/graphql-client.test.ts#L56-L70
  • src/hooks/useCursorEventsQuery.ts#L96-L96
  • src/hooks/useCursorEventsQuery.test.ts#L81-L110
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/graphql-client.ts` around lines 35 - 38, Use one partial-response
contract across the client, hook, and tests: in src/lib/graphql-client.ts lines
35-38 retain GraphQLPartialError, keep its `@throws` documentation accurate at
lines 84-86, and throw GraphQLPartialError with both json.errors and json.data
at lines 116-122. Update src/lib/graphql-client.test.ts lines 56-70 to assert
the typed rejection and both payloads. In src/hooks/useCursorEventsQuery.ts line
96, adapt GraphQLPartialError by returning its data to React Query, and update
src/hooks/useCursorEventsQuery.test.ts lines 81-110 to verify partial-data
recovery through that adapter.

Comment on lines +131 to +136
// Partial failure: render what we got, warn the user
if (err instanceof GraphQLPartialError) {
const partial = err.data as GraphQLResponse;
if (partial?.profiles) setProfiles(partial.profiles);
if (partial?.totalProfiles != null) setTotal(partial.totalProfiles);
toast.warning("Some user data failed to load. Showing partial results.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Clear failed sections instead of retaining stale results.

If the profiles resolver fails, this branch retains rows from the previous page or sort. If totalProfiles fails, it retains the previous pagination total.

Represent partial fields as nullable. Set a safe replacement for each failed field and render a section-specific fallback.

Proposed state handling
-        const partial = err.data as GraphQLResponse;
-        if (partial?.profiles) setProfiles(partial.profiles);
-        if (partial?.totalProfiles != null) setTotal(partial.totalProfiles);
+        const partial = err.data as Partial<GraphQLResponse>;
+        setProfiles(partial.profiles ?? []);
+        setTotal(partial.totalProfiles ?? 0);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Partial failure: render what we got, warn the user
if (err instanceof GraphQLPartialError) {
const partial = err.data as GraphQLResponse;
if (partial?.profiles) setProfiles(partial.profiles);
if (partial?.totalProfiles != null) setTotal(partial.totalProfiles);
toast.warning("Some user data failed to load. Showing partial results.");
// Partial failure: render what we got, warn the user
if (err instanceof GraphQLPartialError) {
const partial = err.data as Partial<GraphQLResponse>;
setProfiles(partial.profiles ?? []);
setTotal(partial.totalProfiles ?? 0);
toast.warning("Some user data failed to load. Showing partial results.");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/admin.users.tsx` around lines 131 - 136, Update the
GraphQLPartialError handling in the route’s data-loading flow to track profiles
and totalProfiles as nullable partial fields, clearing each failed field instead
of retaining prior state. Apply safe replacements for missing fields, such as an
empty profile list and a neutral pagination total, and render section-specific
fallbacks while preserving successfully returned partial data.

@krushit1307 krushit1307 added the Blue All CI checks are passing on this PR label Aug 4, 2026
@krushit1307
krushit1307 merged commit 2e8fc05 into krushit1307:main Aug 4, 2026
3 of 10 checks passed
@Diwakar-odds

Copy link
Copy Markdown
Contributor Author

Hi @krushit1307, I noticed this PR was merged/closed but seems to be missing the good pr label. Could you please take a look and add the label if it qualifies? Thank you!

@Diwakar-odds

Copy link
Copy Markdown
Contributor Author

Hi @krushit1307!

Thank you so much for reviewing and merging this PR!

As this PR contributes substantial feature implementation and code quality enhancements, could you please add the applicable ECSoC '26 labels to this PR when you have a moment?

  • Requested Labels: good-pr
  • Program Tag: ECSoC26

Thank you for your time and for maintaining this repository!

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

Labels

Blue All CI checks are passing on this PR bug Something isn't working ECSoC26-L3 ECSoC26 Elite Coders Summer Of Code'26 - Open Source Program frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Handle GraphQL query partial failure errors gracefully

2 participants