Skip to content

Conversation

Jetshree
Copy link
Contributor

@Jetshree Jetshree commented Sep 7, 2025

Description

Fixed newsletter form from showing fake success with console errors to properly displaying "Something went wrong" when it actually fails. The newsletter subscription form has been enhanced to handle network errors more gracefully by converting its submission logic to use async/await, implementing robust try-catch blocks for error handling, and resetting form fields upon successful submission to improve user experience and reliability.

Before:
image

After:
image

Related issue(s)

See also #4366

Summary by CodeRabbit

  • New Features

    • Newsletter subscription form now auto-clears name and email after a successful submission.
  • Bug Fixes

    • Improved reliability of submissions with clearer success/failure handling; network and runtime errors are now caught and surfaced.
  • Refactor

    • Submission flow streamlined for more consistent feedback and stability during network issues and edge cases.

Copy link

netlify bot commented Sep 7, 2025

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 8be5283
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/68bd6e53a6bc38000998a244
😎 Deploy Preview https://deploy-preview-4397--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

coderabbitai bot commented Sep 7, 2025

Walkthrough

Refactors the newsletter subscription handler to use async/await with try/catch for the POST to /.netlify/functions/newsletter_subscription; sets FormStatus based on response status, awaits res.json(), and clears name/email on successful submission. handleSubmit becomes async; promise chaining removed.

Changes

Cohort / File(s) Summary
Newsletter subscribe flow refactor
components/NewsletterSubscribe.tsx
Converted handleSubmit to async/await with try/catch; POST to /.netlify/functions/newsletter_subscription; set FormStatus.SUCCESS on 200 else FormStatus.ERROR; await res.json(); clear name/email on success; removed .then chaining.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor U as User
    participant C as NewsletterSubscribe (Component)
    participant F as Netlify Function\n/.netlify/functions/newsletter_subscription
    participant S as FormStatus

    U->>C: Submit form (name, email)
    rect rgb(235, 245, 255)
      note right of C: async handler (try/catch)
      C->>F: POST name,email
      F-->>C: HTTP Response (status, json)
    end

    alt status 200
      C->>S: set SUCCESS
      note right of C: clear name & email
    else status != 200
      C->>S: set ERROR
    end

    opt network/runtime error
      C->>S: set ERROR
      note right of C: error caught in catch
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ready-to-merge

Suggested reviewers

  • derberg
  • sambhavgupta0705
  • vishvamsinh28
  • akshatnema
  • Mayaleeeee

Poem

I thump my paws—await, don’t then!
A fetch hops out, returns again.
If two-oh-oh sings, I twitch with cheer,
I clear the fields: all crisp, all clear.
If storms roll in, I set ERROR—still near. 🐇

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


📜 Recent 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 0142ebe and 8be5283.

📒 Files selected for processing (1)
  • components/NewsletterSubscribe.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/NewsletterSubscribe.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

codecov bot commented Sep 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (cf11f17) to head (8be5283).

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #4397   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           22        22           
  Lines          778       778           
  Branches       144       144           
=========================================
  Hits           778       778           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@asyncapi-bot
Copy link
Contributor

asyncapi-bot commented Sep 7, 2025

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 34
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-4397--asyncapi-website.netlify.app/

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: 2

🧹 Nitpick comments (3)
components/NewsletterSubscribe.tsx (3)

62-66: Reset-on-success is good; avoid timer leaks/races.

You schedule a new reset timer every status change but never clear prior ones or on unmount. Keep a ref to the timer, clear before setting a new one, and clean up on unmount.

Example (outside selected lines):

// add imports: useRef, useEffect
const resetTimerRef = React.useRef<number | null>(null);

const setFormStatus = (formResponse: FormStatus) => {
  setStatus(formResponse);
  if (formResponse === FormStatus.SUCCESS) {
    setName('');
    setEmail('');
  }
  if (resetTimerRef.current) window.clearTimeout(resetTimerRef.current);
  resetTimerRef.current = window.setTimeout(() => setStatus(FormStatus.NORMAL), 10_000);
};

React.useEffect(() => () => {
  if (resetTimerRef.current) window.clearTimeout(resetTimerRef.current);
}, []);

72-75: Call preventDefault before setting state.

Minor ordering nit to avoid any chance of form submission racing with state updates.

-  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
-    setStatus(FormStatus.LOADING);
-    event.preventDefault();
+  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
+    event.preventDefault();
+    setStatus(FormStatus.LOADING);

81-89: Add a fetch timeout to avoid indefinite LOADING if the backend stalls.

Use AbortController to fail fast and surface a proper error state.

Example (outside selected lines):

const controller = new AbortController();
const timeoutId = window.setTimeout(() => controller.abort(), 10_000);

try {
  const res = await fetch('/.netlify/functions/newsletter_subscription', {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json' },
    signal: controller.signal,
  });
  // ...
} finally {
  window.clearTimeout(timeoutId);
}
📜 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 cf11f17 and 9f6e81b.

📒 Files selected for processing (1)
  • components/NewsletterSubscribe.tsx (2 hunks)

Comment on lines 90 to 94
if (res.status === 200) {
setFormStatus(FormStatus.SUCCESS);
} else {
setFormStatus(FormStatus.ERROR);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Treat any 2xx as success (use res.ok).

Hard-coding 200 will mark 201/202/204 as failures, reintroducing “false error” states.

-      if (res.status === 200) {
+      if (res.ok) {
         setFormStatus(FormStatus.SUCCESS);
       } else {
         setFormStatus(FormStatus.ERROR);
       }
📝 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
if (res.status === 200) {
setFormStatus(FormStatus.SUCCESS);
} else {
setFormStatus(FormStatus.ERROR);
}
if (res.ok) {
setFormStatus(FormStatus.SUCCESS);
} else {
setFormStatus(FormStatus.ERROR);
}
🤖 Prompt for AI Agents
In components/NewsletterSubscribe.tsx around lines 90 to 94, the code treats
only status 200 as success which will misclassify other successful 2xx responses
(201/202/204) as errors; update the conditional to use res.ok (or check
res.status >= 200 && res.status < 300) so any 2xx is treated as success, and
keep the existing setFormStatus(FormStatus.SUCCESS) /
setFormStatus(FormStatus.ERROR) calls otherwise.

Comment on lines +96 to +99
await res.json();
} catch (error) {
setFormStatus(FormStatus.ERROR);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused await res.json(); it can flip SUCCESS to ERROR.

If the backend returns 204/no body or non-JSON, this throws and the catch sets ERROR even after a 2xx. Since the body isn’t used, drop the parse or guard it.

-      await res.json();

Optional guarded read:

if (res.headers.get('content-type')?.includes('application/json')) {
  await res.json().catch(() => null);
}
🤖 Prompt for AI Agents
In components/NewsletterSubscribe.tsx around lines 96 to 99, remove the
unconditional await res.json() which can throw on 204/no-body or non-JSON
responses and incorrectly trigger the catch branch; either drop the parse
entirely since the body isn't used, or perform a guarded parse by checking
res.headers.get('content-type') for 'application/json' and only then await
res.json().catch(() => null) so JSON parse errors don't flip a successful 2xx
response into FormStatus.ERROR.

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