اذهب إلى المحتوى
  • 0

مشكلة Uncaught (in promise) Error: `headers` was called outside a request scope. next.js 14

فينيكس العربي

السؤال

أعمل على مشروع قمت بعمله بـ nextJS 14 و typescript وكان الموقع يعمل بشكل طبيعي ولكن فجأة ظهر خطأ عندما أنتقل لصفحة chats يتوقف المتصفح عن الإستجابة ويحدث render لانهائي كما ترون في الصورة أدناه

nextjs14.thumb.png.79033471b5ca948ba78a80a2f67787a5.png

 

وفي أعلى الكونسول يظهر تحذير موضح في الصورة التي في الأسفل

 

nextjs14asyncawait.thumb.png.0cfadca156901c72ae9545789bf5cd9b.png

 

هذا ملف chats.tsx 

"use client";

import { auth } from "@/auth";
import { getUsersForSidebar } from "@/lib/data";
import Chat from "./chat";
import { useState } from "react";
import { IChatDocument } from "@/models/chatModel";


const Chats = async () => {
  const [selectedChat, setSelectedChat] = useState<IChatDocument | null>(null);
  const session = await auth();
  
  const chats = session?.user ? await getUsersForSidebar(session.user._id) : [];

  const handleSelectedChat = (chat: IChatDocument) => setSelectedChat(chat);

  return (
    <nav className="flex-1 overflow-y-auto">
      <ul>
        {chats.map((chat) => (
          <Chat
            key={chat._id}
            chat={chat}
            handleSelectedChat={handleSelectedChat}
            selectedChat={selectedChat}
          />
        ))}
      </ul>
    </nav>
  );
};

export default Chats;

 

الخطأ الذي يحدث فيه render لانهائي يشير إلى هذا السطر

const session = await auth();

لذلك قد يكون ملف auth.ts له علاقة بالخطأ لهذا الكود الخاص بالملف في الأسفل

 

import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import { connectToMongoDB } from "./lib/db";
import User from "./models/userModel";
import randomString from "random-string";

export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [
    GitHub({
      clientId: process.env.AUTH_GITHUB_ID,
      clientSecret: process.env.AUTH_GITHUB_SECRET,
    }),
  ],
  secret: process.env.AUTH_SECRET,

  callbacks: {
    async session({ session }) {
      try {
        await connectToMongoDB();
        if (session.user) {
          const user = await User.findOne({ email: session.user.email });
          if (user) {
            session.user._id = user._id;
            session.user.userCode = user.userCode;
            return session;
          } else {
            throw new Error("User Not Found!");
          }
        } else {
          throw new Error("Invalid Session!");
        }
      } catch (error) {
        console.log(error);
        // Throw an error or return null to indicate an invalid session
        throw new Error("Invalid session");
      }
    },
    async signIn({ account, profile }) {
      if (account?.provider === "github") {
        await connectToMongoDB();

        try {
          const user = await User.findOne({ email: profile?.email });

          // Sign up user if not found
          if (!user) {
            const coding = randomString({
              length: 8,
              numeric: true,
              letters: true,
              special: false,
            });
            const newUser = await User.create({
              username: profile?.login,
              email: profile?.email,
              userCode: coding,
              fullName: profile?.name,
              avatar: profile?.avatar_url,
            });

            await newUser.save();
          }
          return true; // indicate successful sign-in
        } catch (error) {
          console.log("Sign in Error: ", error);
          return false;
        }
      }

      return false;
    },
  },
});

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

المشكلة أنك تحاول استخدام دالة غير مناسبة في جهة العميل client-side بدلاً من جهة الخادم server-side.

ففي Next.js، استخدام الدوال غير المتزامنة async في مكونات العميل يؤدي إلى مشاكل، حيث أن تلك الدوال يجب أن تُنفذ داخل دوال الخادم أو عند تحميل البيانات data fetching.

عليك إعادة هيكلة المكون Chats والإعتماد على useEffect و useState لتحميل البيانات عند تحميل المكون بدلاً من استخدام دالة غير متزامنة في المكون ونقل دالة auth واستخدامها في useEffect لتحميل البيانات بعد تحميل المكون.

"use client";

import { useEffect, useState } from "react";
import { auth } from "@/auth";
import { getUsersForSidebar } from "@/lib/data";
import Chat from "./chat";
import { IChatDocument } from "@/models/chatModel";

const Chats = () => {
  const [selectedChat, setSelectedChat] = useState<IChatDocument | null>(null);
  const [chats, setChats] = useState<IChatDocument[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const session = await auth();
        if (session?.user) {
          const chatsData = await getUsersForSidebar(session.user._id);
          setChats(chatsData);
        }
      } catch (error) {
        setError("Failed to load chats");
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  const handleSelectedChat = (chat: IChatDocument) => setSelectedChat(chat);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>{error}</p>;

  return (
    <nav className="flex-1 overflow-y-auto">
      <ul>
        {chats.map((chat) => (
          <Chat
            key={chat._id}
            chat={chat}
            handleSelectedChat={handleSelectedChat}
            selectedChat={selectedChat}
          />
        ))}
      </ul>
    </nav>
  );
};

export default Chats;

باستخدام useEffect لتحميل البيانات بعد تحميل المكون نتجنب استخدام دوال غير متزامنة مباشرة داخل المكون التي تسبب مشاكل خاصة في بيئة العميل.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

جربت الحل ولم يعد يقوم بـ render لانهائي ولكن لم تعد المحادثات تظهر فقمت بتعديل الكود قليلا ومازالت المحادثات لاتظهر فقمت بنسخ رسالة الخطأ فظهرت لي هذا الرسالة في الكونسول

`headers` was called outside a request scope. Read more:

https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

هذا الكود بعد تعديله

 

"use client";

import { Key, useEffect, useState } from "react";
import { auth } from "@/auth";
import { getUsersForSidebar } from "@/lib/data";
import Chat from "./chat";
import { IChatDocument } from "@/models/chatModel";

const Chats = () => {
  const [selectedChat, setSelectedChat] = useState<IChatDocument | null>(null);
  const [chats, setChats] = useState<IChatDocument[] | null | any>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const session = await auth();
        if (session?.user) {
          const chatsData = session?.user
            ? await getUsersForSidebar(session.user._id)
            : [];
          setChats(chatsData);
        }
        return;
      } catch (error: any) {
        setError(error.message);
        console.log(error.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  const handleSelectedChat = (chat: IChatDocument) => setSelectedChat(chat);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>{error}</p>;

  return (
    <nav className="flex-1 overflow-y-auto">
      <ul>
        {chats.map((chat: { _id: Key | null | undefined }) => (
          <Chat
            key={chat._id}
            chat={chat}
            handleSelectedChat={handleSelectedChat}
            selectedChat={selectedChat}
          />
        ))}
      </ul>
    </nav>
  );
};

export default Chats;

 

تم التعديل في بواسطة فينيكس العربي
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...