Next.js Discord

Discord Forum

Redirect issue in Router handler

Unanswered
Painted Redstart posted this in #help-forum
Open in Discord
Painted RedstartOP
Hi everyone,


New to Programming and NextJS.
I am trying to redirect based on the response I received from MongoDB using an HTTP request. here is my bare version of the code.

import { NextResponse } from "next/server";

import { redirect } from "next/navigation";

export const runtime = "edge";

export const POST = async (request: Request) => {
  const { question, authorID } = await request.json(); 
    try {
      const mongoresponse = await fetch(
       // mongo api call
      );

     
      // mongo  result = something;

        if (something > 0) {
          try {
            // do some other opertaion like streaming
          } catch (error) {
            console.error(error);
            return NextResponse.json({ reply: "error" });
          }
        } else {
          redirect("/home");  --- failing
        }
      } else {
        return NextResponse.json({
          reply: "Invalid session or session end time",
        });
      }
    } catch (error) {
      console.error(error);
      return NextResponse.json({ reply: "error" });
    }
};


error:
Error: NEXT_REDIRECT] {
  digest: 'NEXT_REDIRECT;replace;/purchase;false',
  mutableCookies: ResponseCookies {"__client_uat":{"name":"__client_uat","value":"1701959817","path":"/"},"__clerk_db_jwt":{"name":"__clerk_db_jwt","value":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXYiOiJkdmJfMlZ3aXVBYm9tOEtVc082OUoyWVk2

46 Replies

Painted RedstartOP
Thanks @Ray . I tried with redirect but it printing hmtl page on the UI instead of redirecting. By the way, my UI Post Call is response.body.getReader() since I am streaming text from the Router handler.
Painted RedstartOP
hmm no luck

meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/2d141e1a38819612-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/app/layout.css?v=1701965922593" data-precedence="next_static/css/app/layout.css"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack.js?v=1701965922593"/><script src="/_next/static/chunks/main-app.js?v=1701965922593" async=""></script><script src="/_next/static/chunks/app-pages-internals.js" async=""></script><script src="/_next/static/chunks/app/layout.js" async=""></script><script src="/_next/static/chunks/app/(root)/layout.js" async=""></script><script src="/_next/static/chunks/app/(root)/purchase/page.js" async=""></script><title>QA GPT | Home Page</title><meta name="description" content="Home Page for QAGPT.CO"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="1024x1024"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills.js" noModule="


```
it is printing all the page source on UI @Ray
how are you submitting the form?
ok try again with this
return NextResponse.redirect(new URL("/home", req.url), {status: 303})
Painted RedstartOP
Same issue. @Ray Thanks for your help in advance
 here is the front end stream code
  const response = await fetch("/api/completion", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
            
            }),
          });
          const reader = response.body!.getReader();
          let answer = "";
          const processStream = async () => {
            while (true) {
              const { done, value } = await reader.read();
              if (done) break;

              try {
                const text = new TextDecoder().decode(value);
                setStreamData((prevData) => prevData + text);
                answer += text; // Append the text to the answer variable
              } catch (error) {
                console.log("Error in processing stream:", error);
                
              }
            }
          };

          processStream()            
            .then(() => {
              console.log("Question created successfully");
              // Additional code to execute after createQuestion is completed
            })
            .catch((error) => {
              console.log(
                "Error in processing stream or creating question:",
                error
              );
              // Handle the error as needed
            });
 
Painted RedstartOP
@Ray I can see it is routing but on front end it displaying even after I did response.status === 200
const reader = response.body!.getReader(); have you moved this line inside the if block?
Painted RedstartOP
yes and I did console.log(response.statu) it shows 200
can you show the frontend code again
Painted RedstartOP
 const response = await fetch("/api/completion", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
            
            }),
          });
          console.log(response.status);
          if (response.status === 200) {
          const reader = response.body!.getReader();
          let answer = "";
          const processStream = async () => {
            while (true) {
              const { done, value } = await reader.read();
              if (done) break;

              try {
                const text = new TextDecoder().decode(value);
                setStreamData((prevData) => prevData + text);
                answer += text; // Append the text to the answer variable
              } catch (error) {
                console.log("Error in processing stream:", error);
                
              }
            }
          };

          processStream()            
            .then(() => {
              console.log("Question created successfully");
              // Additional code to execute after createQuestion is completed
            })
            .catch((error) => {
              console.log(
                "Error in processing stream or creating question:",
                error
              );
              // Handle the error as needed
            });
          } else {
            console.log("you are re routed to login page");
            // Handle the error as needed
          }  
else {
          // eslint-disable-next-line no-undef
          return NextResponse.redirect(new URL("/login", request.url), {
            status: 303,
          });
        }
backend api
Painted RedstartOP
at least the redirected didn't print any on the page
but still redirect didn't happened
oh I think you need to handle the redirect on client side since you are doing client side fetching
do it with useRouter from next/navigation
Painted RedstartOP
ok but in api how do you want me to return? Can I return a json object? if I am doing a NextResponse.json , how to validate in if block?
Thanks Man for your support!! @Ray
@Painted Redstart ok but in api how do you want me to return? Can I return a json object? if I am doing a NextResponse.json , how to validate in if block?
yes you can. for example
  return NextRepsonse.json({ success: true, data: {} })

redirect when success is not true and only include the data if success is true
Painted RedstartOP
TypeError: Failed to execute 'json' on 'Response': body stream already read
at stopListening
show the backend code
Painted RedstartOP
import { NextResponse } from "next/server";

import { redirect } from "next/navigation";

export const runtime = "edge";

export const POST = async (request: Request) => {
  const { question, authorID } = await request.json(); 
    try {
      const mongoresponse = await fetch(
       // mongo api call
      );

     
      // mongo  result = something;

        if (something > 0) {
          try {
            // do some other opertaion like streaming
          } catch (error) {
            console.error(error);
            return NextResponse.json({ reply: "error" });
          }
        } else {
         return NextResponse.json({ reply: "Session expired" });
        }
      } else {
        return NextResponse.json({
          reply: "Invalid session or session end time",
        });
      }
    } catch (error) {
      console.error(error);
      return NextResponse.json({ reply: "error" });
    }
}; 
Session expired section
One type is streaming and one type is json
where is the streaming?
is there a return after streaming?
Painted RedstartOP
yes in try block return new StreamingTextResponse(stream);
} catch (error) {
Painted RedstartOP
 if (something > 0) {
   try {
    return streaming 
  } catch {
  
  }
} else {
   console.log("I am here and sending Json");
  return NextResponse.json({reply:"error"})
}
can you try return early if something < 0? like
  if (something <= 0) {
    return NextResponse.json({reply:"error"})
  }

  return streaming
Painted RedstartOP
Tried no change and Even I removed the stream block @Ray
by default it is taking as streaming
or put redirect outside of the try catch
or throw the error if error.message === NEXT_REDIRECT is catched inside the try catch
@Painted Redstart We tried all of them. <@194128415954173952>
how did you call the route
afaik [fetch() can't handle redirects](https://github.com/vercel/next.js/discussions/34991)
so you have to redirect manually from client-side
so what seems to be the issue?
it seems that the original issue is already answered
Painted RedstartOP
I have two types of return, one is streaming , one is Json based one if and else condition. On front end I need help to differentiate if streaming process the stream, if Json reroute to home page. But, I couldn't able to do it. @aardani