Skip to content

fix/improved error handling in blocks#436

Merged
lukasz-hycom merged 9 commits intomainfrom
feature/blocks_improved-error-handling
Dec 5, 2025
Merged

fix/improved error handling in blocks#436
lukasz-hycom merged 9 commits intomainfrom
feature/blocks_improved-error-handling

Conversation

@lukasz-hycom
Copy link
Copy Markdown
Contributor

@lukasz-hycom lukasz-hycom commented Dec 4, 2025

What does this PR do?

  • improved error handling during data fetching in blocks

Key Changes

  • added an error message displayed in a toast when an attempt to fetch data fails, instead of crashing the entire block

How to test

  • Open Storybook and any block that relies on data fetched from api-harmonization e.g. article-search (the toast should appear in the lower right corner)

Summary by CodeRabbit

  • New Features

    • Added user-facing destructive toasts for failed API requests across search, lists, detail and pagination flows.
    • Introduced use of global/localized labels to populate notification messages.
  • Bug Fixes

    • Improved runtime error handling to prevent silent failures and preserve UI state on errors.
    • Ensured suggestions and lists reset when no results are returned; surfaced notification-marking errors to users.

✏️ Tip: You can customize this high-level summary in your review settings.

@lukasz-hycom lukasz-hycom self-assigned this Dec 4, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 4, 2025

Walkthrough

Added try/catch error handling and destructive localized toast notifications via a global labels context across multiple client-side block components; one server-side file received a non-functional whitespace change.

Changes

Cohort / File(s) Summary
Client blocks — error handling & toasts
packages/blocks/article-search/src/frontend/ArticleSearch.client.tsx, packages/blocks/category/src/frontend/Category.client.tsx, packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx, packages/blocks/notification-details/src/frontend/NotificationDetails.client.tsx, packages/blocks/notification-list/src/frontend/NotificationList.client.tsx, packages/blocks/order-details/src/frontend/OrderDetails.client.tsx, packages/blocks/order-list/src/frontend/OrderList.client.tsx, packages/blocks/orders-summary/src/frontend/OrdersSummary.client.tsx, packages/blocks/service-list/src/frontend/ServiceList.client.tsx, packages/blocks/ticket-list/src/frontend/TicketList.client.tsx
Wrapped asynchronous SDK/API calls in try/catch, imported and used toast and useGlobalContext() to surface destructive, localized error toasts (using labels.errors.requestError.title / content); success paths remain unchanged.
Formatting
packages/blocks/article-search/src/frontend/ArticleSearch.server.tsx
Non-functional whitespace/formatting change (blank line insertion).
Changeset metadata
.changeset/major-chefs-cough.md
Added changeset noting minor version bumps for multiple @o2s/blocks packages with summary "improved error handling".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Attention areas:
    • Verify consistent imports and no duplicate/unused imports of toast and useGlobalContext.
    • Ensure labels.errors.requestError.title and labels.errors.requestError.content exist or are safely guarded.
    • Review updated useEffect dependency arrays (e.g., NotificationDetails) for correctness and unintended re-renders.
    • Confirm error branches do not alter success-state updates or leak partial state.

Suggested reviewers

  • marcinkrasowski

Poem

🐰 I hopped through code with whiskers bright,
Wrapped every fetch to guard the night.
When things go bump, a toast will sing,
So devs can fix the wobbling thing.
Hooray — no silent errors in sight! 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: improved error handling across multiple block components to gracefully handle data fetching failures.
Description check ✅ Passed The description covers the main purpose and how to test, but is missing the Related Ticket(s) section and lacks detailed explanation of side effects and broader impact.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/blocks_improved-error-handling

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (8)
packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1)

51-63: Error handling improves user feedback.

The try/catch block successfully prevents crashes and provides user feedback via toast, which aligns with the PR objectives.

Consider these optional enhancements:

  • Error logging: Log caught errors to aid debugging and monitoring (e.g., console.error('Invoice filter failed:', _error)).
  • Specific error messages: Differentiate between error types (network failures, auth issues, server errors) to provide more actionable feedback to users.
packages/blocks/notification-details/src/frontend/NotificationDetails.client.tsx (1)

49-56: Consider removing label strings from the dependency array.

The labels.errors.requestError.content and labels.errors.requestError.title dependencies could trigger unnecessary effect re-runs if the labels object is recreated on each render. Since these values are only referenced in the error handler (not in the effect's core logic), they don't need to be dependencies.

Apply this diff to optimize the dependency array:

     }, [
         component.accessToken,
         component.id,
-        labels.errors.requestError.content,
-        labels.errors.requestError.title,
         locale,
         notification.status.value,
     ]);
packages/blocks/order-list/src/frontend/OrderList.client.tsx (1)

60-71: Error handling in handleFilter is robust; consider deduping toast config

Wrapping the fetch in try/catch and surfacing a destructive toast with localized labels.errors.requestError greatly improves resilience and UX compared to a hard failure.

If you want to DRY things up (since handleReset uses the same toast), you could extract a tiny helper in this component:

const showRequestErrorToast = () =>
  toast({
    variant: 'destructive',
    title: labels.errors.requestError.title,
    description: labels.errors.requestError.content,
  });

and call showRequestErrorToast() from both handlers.

packages/blocks/service-list/src/frontend/ServiceList.client.tsx (1)

8-11: Consistent localized toast handling for fetch errors; small reuse opportunity

The new error handling in handleFilter and handleReset correctly prevents the block from crashing and surfaces a localized destructive toast using labels.errors.requestError. Logic and control flow look sound.

To reduce duplication and keep future changes to the error copy/toast options in one place, you could extract a tiny local helper like showRequestErrorToast() and reuse it in both handlers (and potentially other blocks following the same pattern).

Also applies to: 35-50, 56-66

packages/blocks/category/src/frontend/Category.client.tsx (1)

6-9: Toast-based pagination error handling looks good; consider minor UX polish

Wrapping sdk.blocks.getCategoryArticles in a try/catch and showing a localized destructive toast via labels.errors.requestError is a solid improvement and keeps state untouched on failures.

Unrelated to this PR’s main goal but worth considering: Pagination (Line 119–124) still has disabled={false}. Wiring that to isPending—as some other blocks do—would prevent duplicate clicks while a fetch is in flight and keep UX consistent across blocks.

Also applies to: 35-63

packages/blocks/ticket-list/src/frontend/TicketList.client.tsx (1)

10-13: Robust ticket-list error handling; duplication of toast snippet is acceptable but extractable

The added try/catch in handleFilter and handleReset correctly guards sdk.blocks.getTicketList and surfaces a localized destructive toast via labels.errors.requestError, while preserving existing state on failure. This is exactly the behavior described in the PR summary.

The toast configuration is duplicated across both handlers; if this pattern continues to spread, consider a small helper (even just within this module) to centralize the “request error” toast shape.

Also applies to: 35-68, 72-84

packages/blocks/article-search/src/frontend/ArticleSearch.client.tsx (1)

7-10: Article search error handling is solid; 60s toast duration may be too aggressive

The new try/catch around sdk.blocks.searchArticles is well done: failures no longer crash the block, stale suggestions are cleared with setSuggestions([]), and a localized destructive toast is shown via labels.errors.requestError.

The only UX concern is the explicit duration: 60000 (Lines 51–56). A 60‑second destructive toast on every failed keystroke‑driven search can easily become noisy, especially on flaky networks. You might want to either:

  • Rely on the default toast duration used elsewhere in the app, or
  • Use a shorter/custom duration specifically for search suggestions, possibly gated/debounced for repeated failures.

Also applies to: 32-58

packages/blocks/order-details/src/frontend/OrderDetails.client.tsx (1)

14-17: Order details now fail gracefully; consider minor typing and reuse improvements

The new try/catch blocks in handleFilter and handleReset correctly wrap sdk.blocks.getOrderDetails, preserving existing items/filters on failure and surfacing a localized destructive toast via labels.errors.requestError. That aligns well with the PR objective of avoiding block‑level crashes.

If you touch this again, two small cleanups could help:

  • Narrow the handleFilter parameter from Partial<any> to Partial<Request.GetOrderDetailsBlockQuery> for better type safety.
  • Extract the repeated toast configuration into a tiny helper to keep the “request failed” UX consistent and easier to adjust.

Also applies to: 106-142, 146-165

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 221dc2c and 237bc04.

📒 Files selected for processing (11)
  • packages/blocks/article-search/src/frontend/ArticleSearch.client.tsx (2 hunks)
  • packages/blocks/article-search/src/frontend/ArticleSearch.server.tsx (1 hunks)
  • packages/blocks/category/src/frontend/Category.client.tsx (3 hunks)
  • packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1 hunks)
  • packages/blocks/notification-details/src/frontend/NotificationDetails.client.tsx (2 hunks)
  • packages/blocks/notification-list/src/frontend/NotificationList.client.tsx (3 hunks)
  • packages/blocks/order-details/src/frontend/OrderDetails.client.tsx (3 hunks)
  • packages/blocks/order-list/src/frontend/OrderList.client.tsx (3 hunks)
  • packages/blocks/orders-summary/src/frontend/OrdersSummary.client.tsx (3 hunks)
  • packages/blocks/service-list/src/frontend/ServiceList.client.tsx (2 hunks)
  • packages/blocks/ticket-list/src/frontend/TicketList.client.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
packages/blocks/article-search/src/frontend/ArticleSearch.client.tsx (3)
packages/ui/src/providers/GlobalProvider/GlobalProvider.tsx (1)
  • useGlobalContext (81-81)
packages/blocks/article-search/src/api-harmonization/article-search.model.ts (1)
  • ArticleList (14-16)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
packages/blocks/category/src/frontend/Category.client.tsx (2)
packages/ui/src/providers/GlobalProvider/GlobalProvider.tsx (1)
  • useGlobalContext (81-81)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
packages/blocks/service-list/src/frontend/ServiceList.client.tsx (2)
packages/ui/src/providers/GlobalProvider/GlobalProvider.tsx (1)
  • useGlobalContext (81-81)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
packages/blocks/notification-details/src/frontend/NotificationDetails.client.tsx (2)
packages/ui/src/providers/GlobalProvider/GlobalProvider.tsx (1)
  • useGlobalContext (81-81)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
packages/blocks/order-list/src/frontend/OrderList.client.tsx (2)
packages/ui/src/providers/GlobalProvider/GlobalProvider.tsx (1)
  • useGlobalContext (81-81)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1)
packages/ui/src/hooks/use-toast.ts (1)
  • toast (189-189)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: deploy-preview
🔇 Additional comments (8)
packages/blocks/article-search/src/frontend/ArticleSearch.server.tsx (1)

27-27: Non-functional formatting change.

This blank line addition improves readability but has no impact on functionality.

packages/blocks/invoice-list/src/frontend/InvoiceList.client.tsx (1)

69-80: Consistent error handling pattern.

The error handling here mirrors the approach in handleFilter (lines 51-63), maintaining consistency across the component. The same optional enhancements suggested for handleFilter apply here: consider adding error logging and more specific error messages for improved debugging and user experience.

packages/blocks/notification-details/src/frontend/NotificationDetails.client.tsx (1)

7-9: Imports and error handling pattern are correct.

The try/catch implementation with localized toast notifications is clean and aligns with the project-wide error handling approach. The labels.errors.requestError structure is guaranteed by the type system (CMS.Model.AppConfig.Labels), so no runtime risk of undefined values. The pattern is consistent across other blocks in the codebase.

packages/blocks/order-list/src/frontend/OrderList.client.tsx (3)

9-12: Toast and GlobalProvider imports look correct

The new toast and useGlobalContext imports are consistent with the referenced modules and their later usage in this component.


37-37: Using useGlobalContext for localized labels is appropriate

Accessing labels from useGlobalContext keeps error messaging aligned with global i18n and with other blocks in this PR; no issues here.


77-87: handleReset error handling matches handleFilter

Reset logic now fails gracefully: on request failure, state is left unchanged and the user sees the same localized destructive toast as in handleFilter. This keeps behavior consistent across both interactions.

packages/blocks/notification-list/src/frontend/NotificationList.client.tsx (1)

11-14: Notification list error handling aligns well with the new pattern

handleFilter and handleReset now correctly guard sdk.blocks.getNotificationList with try/catch and report failures via a localized destructive toast (labels.errors.requestError). This prevents the block from breaking while keeping previously loaded notifications visible.

Implementation is consistent with the other blocks in this PR and doesn’t introduce new correctness issues.

Also applies to: 38-38, 57-72, 75-92

packages/blocks/orders-summary/src/frontend/OrdersSummary.client.tsx (1)

60-112: The 'week' range case is dead code that doesn't execute in the current implementation

The switch statement includes a 'week' case (line 90–92), but the CMS data never provides type: 'week'—only type: 'day' and type: 'month'. So while the logic is indeed identical to the 'day' case, this branch is unreachable based on current CMS configuration.

If 'week' type is intended for future use, note that the current logic would be incorrect: subtracting range days when range represents weeks (e.g., value: 1, type: 'week') would produce too narrow a window. Use subtract(range, 'weeks') instead.

Additionally, the setRange call on line 104 uses a destructive assertion (!) that will throw if the configuration is inconsistent. A guarded fallback (e.g., const found = component.ranges?.find(...); if (found) setRange(found)) would make the code more resilient to data mismatches.

Comment thread packages/blocks/order-details/src/frontend/OrderDetails.client.tsx Outdated
@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
o2s-docs Skipped Skipped Dec 5, 2025 9:37am

@vercel vercel Bot temporarily deployed to Preview – o2s-docs December 5, 2025 09:37 Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
.changeset/major-chefs-cough.md (1)

14-14: Consider a more descriptive summary for release notes.

The summary "improved error handling" is accurate but generic. Consider expanding it to highlight the user-facing benefit, e.g., "improved error handling with toast notifications on API failures" or "graceful error messages on data fetch failures".

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fbf7e0 and e9c1886.

📒 Files selected for processing (1)
  • .changeset/major-chefs-cough.md (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-14T14:21:20.382Z
Learnt from: marcinkrasowski
Repo: o2sdev/openselfservice PR: 357
File: .changeset/cold-showers-camp.md:1-9
Timestamp: 2025-11-14T14:21:20.382Z
Learning: In the o2sdev/openselfservice repository, new packages should always be added with a 'major' version bump in changesets to start at version 1.0.0, not 'minor'.

Applied to files:

  • .changeset/major-chefs-cough.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: deploy-preview
🔇 Additional comments (1)
.changeset/major-chefs-cough.md (1)

1-12: Changeset structure and version strategy are appropriate.

All packages correctly marked as 'minor' for backward-compatible error handling improvements. The list of 10 packages aligns with the blocks receiving enhanced error handling across the PR.

@lukasz-hycom lukasz-hycom merged commit ec8794c into main Dec 5, 2025
7 checks passed
@lukasz-hycom lukasz-hycom deleted the feature/blocks_improved-error-handling branch December 5, 2025 10:06
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.

2 participants