Magnus
Magnus

Reputation: 7829

Why does a 204 response to a fetch() in a React Server Component throw a TypeError (Invalid response status code)?

Consider the following simple Next.js app: https://codesandbox.io/p/sandbox/next-js-app-router-1bvd7d?file=README.md

We have a API route (/api/hello):

export default function handler(req, res) {
  res.status(204).end();
}

And a fetch in a React Server Component (RSC):

export default async function Home() {
  let res;
  try {
    res = await fetch("https://rpvequ-3000.csb.app/api/hello");
    console.log("res.status", res.status);
    console.log("res", res);
  } catch (error) {
    console.log("res in error", res);
    console.log("error", error);
  }
  return (
    <main>
      <p>HELLO WORLD</p>
    </main>
  );
}

The fetch throws the following error message:

TypeError: Response constructor: Invalid response status code 204

If we change the HTTP response from 204 to 202, for instance, the fetch no longer throws an error.

How come we get an error with 204? Is there any way to check if the response was 204 inside the RSC, so we can handle it as needed?


PS: If you are testing it in the Codesandbox or otherwise, remember to delete the .next folder every time you restart the dev server (otherwise fetch() just uses what was cached last time).


Side Note:

The same fetch() in a React Client Component does for some reason not throw an error:

"use client";
import React, { useEffect } from "react";

const ClientComp = ({ children }) => {
  useEffect(() => {
    let res;
    (async () => {
      try {
        res = await fetch("http://localhost:3000/api/hello");
        console.log("res.status", res.status);
        console.log("res", res);
      } catch (error) {
        console.log("res in error", res);
        console.log("error", error);
      }
    })();
  }, []);

  return <div>{children}</div>;
};

export default ClientComp;

In other words, a HTTP response with status code 204 only throws an error when received by a fetch() in a React Server Component, not in a React Client Component.

Upvotes: 3

Views: 2955

Answers (1)

z0oks
z0oks

Reputation: 34

This was a bug in Next.js and it was fixed in this PR https://github.com/vercel/next.js/pull/48354

Upvotes: 1

Related Questions