Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

redirectTo not working, Throwing Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client #529

Open
qualwebs opened this issue Mar 1, 2022 · 4 comments
Labels

Comments

@qualwebs
Copy link

qualwebs commented Mar 1, 2022

馃悰 Bug report

The issue with redirection inside getInitialProps method

Current Behavior

I'm using AfterJS with razzle, Using a class component, and trying to validate the authorization inside getInitialProps method as suggested in the example of afterJs GitHub readme.

Here is the code sample

class Home extends React.Component {
    static async getInitialProps({req, res, match, history, location, ...ctx}) {
        try {
            firstSection = await api.authME('TOKEN');
        }catch (error) {
            if (error.response.status === 401) {
                return { redirectTo: '/login' };
            }
            return { error };
        }
    }
}

Expected behavior

It should redirect to login page if API returns 401 status code, Instead of throwing error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Reproducible example

Suggested solution(s)

Additional context

Your environment

LOCAL

Software Version(s)
React ^17.0.2
After.js ^latest
Razzle ^4.2.6
Razzle Plugins
TypeScript N/A
Node 16.14.0
Browser CHROME
npm/Yarn NPM
Operating System WINDOWS
@qualwebs
Copy link
Author

qualwebs commented Mar 3, 2022

@jaredpalmer If someone can look into please :)

@blinkcat
Copy link

blinkcat commented Mar 7, 2022

@qualwebs This is a bug indeed. if your code return { redirectTo: '/login' }, res.redirectwill be called before res.send.
meanwhile, the html variable will be empty string, so we can try this:

// your server.js in src
server
  .disable('x-powered-by')
  .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
  .get('/*', async (req, res) => {
    try {
      const html = await render({
        req,
        res,
        routes,
        assets,
        chunks,
      });
       if(html){ // add a judgement here
         res.send(html);
      }
    } catch (error) {
      console.error(error);
      res.json({ message: error.message, stack: error.stack });
    }
  });

@jschroed91
Copy link

jschroed91 commented Mar 14, 2022

We ended up using a very similar solution to what @blinkcat posted here.

But instead of if(html){ we did

if (res.statusCode == '302' || res.statusCode == '301') {
  return;
}

res.send(html);

I'm using == there instead of strict comparison === because I don't recall what type res.statusCode was , but obvi a strict comparison would be better. But you get the point

I think in our case html was still getting a value, so that's why we went this route.

@stale
Copy link

stale bot commented Apr 28, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Apr 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants