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

خطأ Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

السؤال

نشر

السلام عليكم.

أواجه الخطأ التالي:

[0] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0]     at new NodeError (node:internal/errors:400:5)
[0]     at ServerResponse.setHeader (node:_http_outgoing:663:11)
[0]     at ServerResponse.header (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\response.js:794:10)
[0]     at ServerResponse.json (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\response.js:275:10)
[0]     at errorHandler (file:///C:/Users/saadaoui/Desktop/MERN%20E-commerce/backend/middlewares/errorMiddleware.js:14:26)
[0]     at Layer.handle_error (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\layer.js:71:5)
[0]     at trim_prefix (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:326:13)
[0]     at C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:286:9
[0]     at Function.process_params (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:346:12)
[0]     at next (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:280:10)

أعتقد أن مكان الخطأ في errorrMiddleware.js

errorrMiddleware.js

const notFound = (req, res, next) => {
  const error = new Error(`Not Found - ${req.originalUrl}`);
  res.status(404);
  next(error);
};

const errorHandler = (err, req, res, next) => {
  let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  let message = err.message;

  // NOTE: checking for invalid ObjectId moved to it's own middleware
  // See README for further info.

  res.status(statusCode).json({
    message: message,
    stack: process.env.NODE_ENV === "production" ? null : err.stack,
  });
};

export { notFound, errorHandler };

server.js

import express from "express";
import dotenv from "dotenv";
import productRoutes from './routes/productRoutes.js'
dotenv.config();
import connectDB from "./config/db.js"
import { errorHandler, notFound } from "./middlewares/errorMiddleware.js";
const port = process.env.PORT || 5000;

connectDB()

const app = express() 
app.use(express.json());

app.use('/api/products', productRoutes)

app.get('/', (req, res) => {
    res.send('API is running ...')
})

app.use(notFound)
app.use(errorHandler)

app.listen(port, () => console.log(`Server is running on port ${port}`))

شكرا للمساعدة

Recommended Posts

  • 0
نشر

أتمنى إرفاق الكود كاملا لتجربته كي أفحصه جيدا.

بشكل عام، الخطأ في الكود هنا نشأ عندما تمت محاولة تعيين رأس الاستجابة بعدما تم بالفعل إرسال الاستجابة إلى العميل، ففي الكود يتم استخدام دالة `()res.status().json` لإرسال الرد في `errorHandler` عند حدوث خطأ ال middleware.

فالمشكلة تتضمن التالي:

  • الموقع: يمكن تحديده من خلال المسار الذي يشير إليه الخطأ. في هذه الحالة، يتم إظهار الموقع كمسار الملف `errorMiddleware.js`.
  • الخطأ: يتم توضيح الخطأ الذي يحدث. في هذه الحالة، يشير الخطأ إلى أنه لا يمكن تعيين رأس الاستجابة بعد إرسالها للعميل، والذي يُطلق الاستثناء `Error [ERR_HTTP_HEADERS_SENT]`.

حاولت أن أشرح رسالة الخطأالتي ظهرت فعند حدوث خطأ في التطبيق، يتم استدعاء `()res.status().json` في ملف `errorMiddleware.js` لإرسال استجابة JSON. ومع ذلك، يحدث خطأ "Cannot set headers after they are sent to the client" لأن الاستجابة قد تم بالفعل إرسالها، وبالتالي يتعذر تعيين رأس الاستجابة مرة أخرى.

ولتجنب هذا الخطأ، يُنصح بالتحقق مما إذا كانت الرؤوس قد تم إرسالها بالفعل قبل تعديلها. يمكن ذلك عن طريق التحقق من خاصية res.headersSent فإذا لم تكن الرؤوس قد تم إرسالها بالفعل، يمكن تعديل الاستجابة بشكل طبيعي، وإلا فإنه يُستدعى () next لتمرير التحكم إلى المنطقة التالية في سلسلة وسائط Express.

وهذا هو الكود الصحيح:

const errorHandler = (err, req, res, next) => {
  let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  let message = err.message;

  if (!res.headersSent) {
    res.status(statusCode).json({
      message: message,
      stack: process.env.NODE_ENV === "production" ? null : err.stack,
    });
  }
  next();
};

export { errorHandler };

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

  • 0
نشر

الكود يبدو صحيحًا، ولكن يمكن أن يكون هناك سبب آخر لظهور الخطأ

اقتباس

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.

يُمكنك محاولة تعديل errorHandler للتحقق من ذلك باضافة هذا السطر للكود :

 if (res.headersSent) {
    return next(err);
  }

وهذا السطر للتحقق من عدم ارسال ال headers  مرتين  ومنع حدوث الخطأ التي اشرت لك به حيث يقوم ب التأكد اذا تم بالفعل إرسال headers، وتجاهل الاستجابة والمرور إلى الوسيط التالي

سيصبح الكود كالتالي :

 

const notFound = (req, res, next) => {
  const error = new Error(`Not Found - ${req.originalUrl}`);
  res.status(404);
  next(error);
};

const errorHandler = (err, req, res, next) => {
  let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  let message = err.message;
  
  //قمت باضافته هنا
   if (res.headersSent) {
    return next(err); 
  }

  // NOTE: checking for invalid ObjectId moved to it's own middleware
  // See README for further info.

  res.status(statusCode).json({
    message: message,
    stack: process.env.NODE_ENV === "production" ? null : err.stack,
  });
};

export { notFound, errorHandler };

ارجو اخباري بالنتيجة وان لم تنجح الرجاء ارفاق ملفات المشروع لمساعدتك بشكل افضل

وبالتوفيق لك 

  • 0
نشر
بتاريخ منذ ساعة مضت قال محمود سعداوي2:

السلام عليكم.

أواجه الخطأ التالي:

[0] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0]     at new NodeError (node:internal/errors:400:5)
[0]     at ServerResponse.setHeader (node:_http_outgoing:663:11)
[0]     at ServerResponse.header (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\response.js:794:10)
[0]     at ServerResponse.json (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\response.js:275:10)
[0]     at errorHandler (file:///C:/Users/saadaoui/Desktop/MERN%20E-commerce/backend/middlewares/errorMiddleware.js:14:26)
[0]     at Layer.handle_error (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\layer.js:71:5)
[0]     at trim_prefix (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:326:13)
[0]     at C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:286:9
[0]     at Function.process_params (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:346:12)
[0]     at next (C:\Users\saadaoui\Desktop\MERN E-commerce\node_modules\express\lib\router\index.js:280:10)

أعتقد أن مكان الخطأ في errorrMiddleware.js

errorrMiddleware.js

const notFound = (req, res, next) => {
  const error = new Error(`Not Found - ${req.originalUrl}`);
  res.status(404);
  next(error);
};

const errorHandler = (err, req, res, next) => {
  let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  let message = err.message;

  // NOTE: checking for invalid ObjectId moved to it's own middleware
  // See README for further info.

  res.status(statusCode).json({
    message: message,
    stack: process.env.NODE_ENV === "production" ? null : err.stack,
  });
};

export { notFound, errorHandler };

server.js

import express from "express";
import dotenv from "dotenv";
import productRoutes from './routes/productRoutes.js'
dotenv.config();
import connectDB from "./config/db.js"
import { errorHandler, notFound } from "./middlewares/errorMiddleware.js";
const port = process.env.PORT || 5000;

connectDB()

const app = express() 
app.use(express.json());

app.use('/api/products', productRoutes)

app.get('/', (req, res) => {
    res.send('API is running ...')
})

app.use(notFound)
app.use(errorHandler)

app.listen(port, () => console.log(`Server is running on port ${port}`))

شكرا للمساعدة

تفضل ملفات المشروع (دون node_odules)

 

test-hsoub.zip

  • 1
نشر
بتاريخ 40 دقائق مضت قال محمود سعداوي2:

تفضل ملفات المشروع (دون node_odules)

 

test-hsoub.zip 577.85 kB · 0 تنزيلات

شكرا على إرفاقك لملفات المشروع.

لقد تصفحتها، ووجدت أن المشكلة تكون بعد الضغط على أي منتج لتصفحه، هنا يظهر لك الخطأ الأول وهو عبارة عن خطأ [ERR_HTTP_HEADERS_SENT]: ويعني أنه لا يمكن تعيين الرؤوس بعد إرسالها إلى العميل في errorMiddleware.js ويحدث هذا الخطأ عادة عند محاولة إرسال أكثر من استجابة واحدة لطلب واحد، وغالبًا ما يكون السبب في ذلك هو إرسال استجابة في middleware أو معالجات الطرق ثم محاولة إرسال استجابة أخرى لاحقًا.

حللت المشكلة من خلال التأكد من إرسال استجابة واحدة فقط لكل طلب، وهنا في ` ، نقوم بتجنب إرسال استجابة إذا تم بالفعل إرسال الرؤوس.من خلال إضافة هذين السطرين في برمجية errorHandler في ملف errorMiddlware.js:

if (res.headersSent) {
    return next(err); // تمرير الخطأ إلى middleware التالي إذا تم بالفعل إرسال الرؤوس
  }

بهذا الشكل:

const errorHandler = (err, req, res, next) => {
  if (res.headersSent) {
    return next(err); // تمرير الخطأ إلى middleware التالي إذا تم بالفعل إرسال الرؤوس
  }

  let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  let message = err.message;

  res.status(statusCode).json({
    message: message,
    stack: process.env.NODE_ENV === "production" ? null : err.stack,
  });
};

export { errorHandler };

بعد حل المشكل يظهر الخطأ التالي كما هو موضح في الصورة، وهو متعلق بالمورد فهو غير موجود والخطأ يكمن في ملف productController.js، ويحدث هذا الخطأ عندما يُتوقع وجود مورد (في هذه الحالة ، هو عبارة عن منتج) ولكنه لا يتم العثور عليه.لضمان التعامل الصحيح مع الأخطاء وإرجاع الاستجابات المناسبة عند عدم العثور على الموارد، يمكن تصحيح الكود من خلال استرداد المنتج باستخدام ال Id بالشكل الصحيح بهذا الشكل في ملف productController.js،
 

import asyncHandler from "../middlewares/asyncHandler.js";
import Product from "../models/productModel.js";

/**
 * desc   Fetch All Products
 * route  Get /api/products
 * access Public
 */
const getProducts = asyncHandler( async(req, res) => {
    const products = await Product.find({})
    res.json(products)
});

/**
 * desc   Fetch Product By Id
 * route  Get /api/products/id
 * access Public
 */
const getProductById = asyncHandler(async (req, res) => {
    const product = await Product.findById(req.params.id);
    if (product) {
        res.json(product);
        return; // Add return here to exit the function after sending the response
    }
    
    res.status(404).json({ message: 'Resource not found' }); // Use 404 status for resource not found
});

export {
    getProducts,
    getProductById
};

وهكذا لن تظهر أي مشكلة.

MernShop.png

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...