Skip to content

Conversation

acicovic
Copy link
Collaborator

@acicovic acicovic commented Sep 23, 2025

Description

With this PR, we're including a few additional errors that exist in the Suggestions API but weren't being captured in our error handling class. We're also unifying the customization of error messages and hints under a single function, for greater simplicity and separation of concerns.

Motivation and context

Closes #3700.

How has this been tested?

The related E2E test was updated, to verify that the newly added errors are categorized as "hard errors"

Summary by CodeRabbit

  • New Features

    • Added new error codes for invalid requests, response validation failures, and “no data with manual linking.”
    • Improved user-facing error messages, including a dedicated message for missing credentials.
    • Introduced a mechanism to customize error messages, enabling better localization and tailored hints.
  • Refactor

    • Consolidated multiple error scenarios into shared, clearer messages.
    • Standardized error rendering to consistently return UI elements with optional hints.
  • Tests

    • Updated test coverage to include new error codes and validate hard-error handling.

@acicovic acicovic self-assigned this Sep 23, 2025
Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

📝 Walkthrough

Walkthrough

Adds three new public error codes to ContentHelperErrorCode, introduces a protected CustomizeErrorMessaging hook, and updates ContentHelperError message/hint rendering to group certain codes under shared messages and to render credential-related errors via EmptyCredentialsMessage. Tests updated to include the new error codes as hard errors.

Changes

Cohort / File(s) Summary
Error handling and messaging
src/content-helper/common/content-helper-error.tsx
Added error codes: ParselySuggestionsApiNoDataManualLinking, ParselySuggestionsApiResponseValidationError, ParselySuggestionsInvalidRequest. Introduced protected CustomizeErrorMessaging(). Consolidated messaging across related codes. Message() now routes credential errors to EmptyCredentialsMessage and others to ContentHelperErrorMessage, preserving hint rendering.
Tests
tests/js/content-helper/content-helper-error.test.ts
Updated test arrays to include the three new error codes as non-soft (hard) errors; no retry logic changes beyond expectations.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor UI as UI
  participant CHE as ContentHelperError
  participant Msg as ContentHelperErrorMessage
  participant Ecm as EmptyCredentialsMessage

  UI->>CHE: Message(props?)
  alt Credential-related code
    CHE-->>Ecm: Render EmptyCredentialsMessage
    Ecm-->>UI: React element
  else Non-credential code
    CHE->>CHE: Select message + optional hint (incl. new codes)
    CHE-->>Msg: Render ContentHelperErrorMessage(message, hint)
    Msg-->>UI: React element
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Feature: PCH

Suggested reviewers

  • vaurdan
  • alecgeatches

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly identifies the modified file and the primary intent of the change — adding more errors to content-helper-error.tsx — which matches the changes summarized in the diff. It is concise and specific enough for a reviewer scanning PR history to understand the main change.
Linked Issues Check ✅ Passed The changes add the new Suggestions API error codes to ContentHelperErrorCode, update message/hint handling, and adjust tests to classify the new codes as hard errors, which directly implements the coding objective described in issue #3700. The modifications are focused on error handling and tests, aligning with the linked issue's request to capture additional errors.
Out of Scope Changes Check ✅ Passed The diff and test updates are confined to content-helper-error.tsx and its tests, and the added CustomizeErrorMessaging method and message consolidation are within the stated objective to unify message customization, so there are no apparent out-of-scope changes. The raw summary does not show unrelated file or behavioral changes outside the error handling area.
Description Check ✅ Passed The PR description follows the repository template by including Description, Motivation and context, and How has this been tested sections, and it references the linked issue and updated E2E test. The provided information is sufficient to understand the intent and basic verification performed.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update/include-more-errors-to-content-helper-error-tsx

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.

@acicovic acicovic marked this pull request as ready for review September 23, 2025 09:32
@acicovic acicovic requested a review from a team as a code owner September 23, 2025 09:32
Copy link
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 (4)
src/content-helper/common/content-helper-error.tsx (4)

101-102: Prefer camelCase for method names (WordPress JS standards).

Use camelCase for class methods. Rename for consistency.

Apply these diffs:

-		this.CustomizeErrorMessaging();
+		this.customizeErrorMessaging();

And update the method definition:

-protected CustomizeErrorMessaging(): void {
+protected customizeErrorMessaging(): void {

Also applies to: 112-112


104-185: Consolidate the if/else chain into a map for clarity.

A mapping object (code → message) will reduce branching and ease future additions.

Example approach:

const MESSAGE_MAP: Partial<Record<ContentHelperErrorCode, string>> = {
  [ContentHelperErrorCode.AccessToFeatureDisabled]: __(
    'Access to this feature is disabled by the site\'s administration.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiNoAuthorization]: __(
    'This AI-powered feature is opt-in. To gain access, please submit a request <a href="https://wpvip.com/content-helper/#content-helper-form" target="_blank" rel="noopener">here</a>.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiOpenAiError]: __(
    'The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiOpenAiUnavailable]: __(
    'The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiSchemaError]: __(
    'The Parse.ly API returned a validation error. Please try again with different parameters.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsInvalidRequest]: __(
    'The Parse.ly API returned a validation error. Please try again with different parameters.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiNoData]: __(
    'The Parse.ly API couldn\'t find any relevant data to fulfill the request.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiNoDataManualLinking]: __(
    'The Parse.ly API couldn\'t find any relevant data to fulfill the request.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiOpenAiSchema]: __(
    'The Parse.ly API returned an incorrect response.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiResponseValidationError]: __(
    'The Parse.ly API returned an incorrect response.',
    'wp-parsely'
  ),
  [ContentHelperErrorCode.ParselySuggestionsApiAuthUnavailable]: __(
    'The Parse.ly API is currently unavailable. Please try again later.',
    'wp-parsely'
  ),
};

// Then in customizeErrorMessaging():
this.message = MESSAGE_MAP[this.code] ?? this.message;
if (this.code === ContentHelperErrorCode.HttpRequestFailed && this.message.includes('cURL error 28')) {
  this.message = __('The Parse.ly API did not respond in a timely manner. Please try again later.', 'wp-parsely');
}

190-194: Fix HTML attribute and complete JSDoc.

Use class instead of className inside raw HTML, and add @SInCE to the JSDoc. Also end the @param description with a period.

Apply this diff:

  /**
   * Shows a hint in order to provide clarity in regards to the error.
   *
-  * @param {string} hint The hint to display
+  * @param {string} hint The hint to display.
+  * @since 3.21.0
   */
  protected Hint( hint: string ): string {
-    return `<p className="content-helper-error-message-hint" data-testid="content-helper-error-message-hint"><strong>${ __( 'Hint:', 'wp-parsely' ) }</strong> ${ hint }</p>`;
+    return `<p class="content-helper-error-message-hint" data-testid="content-helper-error-message-hint"><strong>${ __( 'Hint:', 'wp-parsely' ) }</strong> ${ hint }</p>`;
  }

196-203: Add @SInCE to Message() JSDoc.

Required by the coding guidelines.

Apply this diff:

  /**
   * Renders the error's message.
   *
   * @param {ContentHelperErrorMessageProps|null} props The props needed for the function.
   *
   * @return {import('react').JSX.Element} The resulting JSX Element.
+  * @since 3.21.0
   */
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d897c8e and 78dc4e2.

⛔ Files ignored due to path filters (8)
  • build/admin-settings.asset.php is excluded by !build/**
  • build/admin-settings.js is excluded by !build/**
  • build/content-helper/dashboard-page.asset.php is excluded by !build/**
  • build/content-helper/dashboard-page.js is excluded by !build/**
  • build/content-helper/dashboard-widget.asset.php is excluded by !build/**
  • build/content-helper/dashboard-widget.js is excluded by !build/**
  • build/content-helper/editor-sidebar.asset.php is excluded by !build/**
  • build/content-helper/editor-sidebar.js is excluded by !build/**
📒 Files selected for processing (2)
  • src/content-helper/common/content-helper-error.tsx (4 hunks)
  • tests/js/content-helper/content-helper-error.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,jsx}: "Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards.
  • Ensure the code is well-documented.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @SInCE tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features."

Files:

  • src/content-helper/common/content-helper-error.tsx
  • tests/js/content-helper/content-helper-error.test.ts
🧬 Code graph analysis (1)
src/content-helper/common/content-helper-error.tsx (1)
src/content-helper/common/content-helper-error-message.tsx (3)
  • ContentHelperErrorMessageProps (11-15)
  • EmptyCredentialsMessage (59-72)
  • ContentHelperErrorMessage (28-47)
⏰ 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: E2E against WordPress latest
🔇 Additional comments (3)
tests/js/content-helper/content-helper-error.test.ts (1)

32-39: New Suggestions API error codes covered as hard errors — LGTM.

The additions align with the enum changes and the intended hard/soft error split.

src/content-helper/common/content-helper-error.tsx (2)

41-48: Enum additions are sensible and consistent.

The new error codes are clearly named, documented with HTTP status comments, and correctly excluded from soft errors.


214-220: Validate trusted HTML sources for dangerouslySetInnerHTML.

Message/hint are injected as HTML. Ensure all call sites and upstream error messages are controlled or sanitized to avoid XSS.

Can you confirm that values passed to the constructor’s message parameter are not derived from untrusted remote input? If any are, consider restricting to a safe subset (e.g., only links) or moving to React nodes with createInterpolateElement for links instead of raw HTML.

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.

Include additional errors in content-helper-error.tsx
1 participant