javascriptreactjsexpressmernreact-fullstack

I am getting an error as : AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE'}


I am developing a MERN stack web application which allows sellers to post their rooms on rent and for users to search and select the best room for them.

Whenever I execute the functionality Post Review the error "AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE'," gets generated. What would be the issue in my code at backend or frontend when I submit the post at frontend.

I have used middleware such as isBuyer which allows only user which is a buyer to post a review for the room.

So here is my code :

FRONTEND CODE :

api.js (This is part of whole code where the backed apis are called)

import axios from 'axios';
const API_BASE_URL = 'http://localhost:5001/api/v1';
export const postReview = async (reviewData, id) => {
    try {
        const response = await axios.post(`${API_BASE_URL}/reviews/post-reviews/${id}`, reviewData, {
            withCredentials: true,
        });
        return response;
    } catch (error) {
        console.error('Error posting review:', error.response ? error.response.data : error.message);
        throw error;
    }
};

PostReview.jsx (Console gives error at line: 15)

import React, { useState } from 'react';
import { postReview } from '../api';

const PostReview = ({ id }) => {
  const [formData, setFormData] = useState({ rating: '', review: '' });
  const [error, setError] = useState(null);

  const handleChange = (e) => {
    setFormData({...formData, [e.target.name]: e.target.value });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const res = await postReview(formData, id);     /* --------- ERROR ---------- */
      console.log(res.data);
    }
    catch (error) {
      console.error('Error submitting review:', error);
      setError(error.response ? error.response.data.message : error.message);
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          type="number"
          min={1}
          max={5}
          name="rating"
          value={formData.rating}
          placeholder='Rating'
          onChange={handleChange}
        />
        <input
          type="text"
          name="review"
          value={formData.review}
          placeholder='Review'
          onChange={handleChange}
        />
        <button type="submit">Post</button>
      </form>
      {error && <p>Error: {error}</p>}
    </div>
  );
};

export default PostReview;

SingleHostel.jsx (Here the PostReview component is used)

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { getSingleHostel } from '../api';
import PostReview from '../components/PostReview';
import { useUser } from '../context/userContext';

const SingleHostel = () => {
  const [room, setRoom] = useState([]);
  const { id } = useParams();
  const { user } = useUser();
  useEffect(() => {
    const fetchHostel = async () => {
      try {
        const res = await getSingleHostel(id);
        setRoom(res.data.hostel);
        console.log(res.data.hostel);
      } catch (error) {
        console.log(error.response ? error.response.data.message : error.message);
      }
    };
    fetchHostel();
  }, [id]);

  return (
    <div>
      <div>
        <h1>{room.name}</h1>
        <h1>{room.location}</h1>
        <h1>{room.address}</h1>
        <h1>{room.rent}</h1>
        <h1>{room.description}</h1>
        <h1>{room.status}</h1>
      </div>
      {user?.isBuyer ? <div> <PostReview id={room._id} /> </div> : null}
    </div>
  );
};

export default SingleHostel;

UserContext.jsx (React Context API form user data)

import React, { createContext, useContext, useState, useEffect } from 'react';
import { getCurrentUser as fetchCurrentUser } from '../api';

const UserContext = createContext();

export const useUser = () => {
  return useContext(UserContext);
};

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const userData = await fetchCurrentUser();
        setUser(userData);
      } catch (error) {
        console.error('Error fetching current user:', error.message);
      }
      setLoading(false);
    };

    fetchUser();
  }, []);

  return (
    <UserContext.Provider value={{ user, setUser, loading }}>
      {children}
    </UserContext.Provider>
  );
};

BACKEND CODE :

review.controllers.js

import {Review} from "../models/review.model.js";

const postReviews = async(req, res) => {
    try{
        const {id} = req.params;
        const {rating, comment} = req.body;
        if([rating, comment].some((data) => data.trim() === "")){
            return res.status(400).json({message: "Please fill all the fields."})
        }
        const review = await Review.create({user: req.user._id, hostel : id, rating, comment});
        res.status(201).json({message: "Review created successfully.", review})
    }
    catch(err){
        res.status(500).json({message: "Internal server error."})
    }
}

const getAllReviewsForHostel = async(req, res) => {
    try{
        const {id} = req.params;
        const reviews = await Review.find({hostel: id}).populate("user", "-password -refreshToken -isSeller -isBuyer");
        if(!reviews){
            return res.status(404).json({message: "No reviews found."})
        }
        res.status(200).json({message: "Reviews found successfully.", reviews})
    }
    catch(error){
        res.status(500).json({message: `Reviews fetching unsuccessfull. ERROR : ${error.message}`});
    }
}

export {postReviews, getAllReviewsForHostel};

userAuthmiddleware.js

import jwt from "jsonwebtoken";
import { User } from "../models/user.model.js";

const verifyUser = async (req, res, next) => {
    try {   
        const token = req.cookies?.accessToken;

        if(!token){
            return res.status(400).json({
                message : "Unauthorised Request! Token not found",
            })
        }

        const decodedToken = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);

        const user = await User.findById(decodedToken._id).select("-password -refreshToken");

        if(!user){
            return res.status(400).json({
                message : "Invalid decoded token",
            })
        }

        req.user = user;
        
        next();
    }
    catch (error){
        return res.status(400).json({
            message : `Invalid user. Authentication Failed ! ERROR : ${error.message}`,
        })
    }
}

export {verifyUser};

userIsBuyer middleware

import { User } from "../models/user.model.js";

const isBuyerAuth = async (req, res, next) => {
    try{
        const user = await User.findById(req.user.id);
        if(user.isBuyer){
            next();
        }
        else{
            return res.status(403).json({message: "You do not have access to this route."});
        }
    }
    catch(error){
        return res.status(500).json({message: `User buyer authentication error. ${error.message}`});
    }
}

export {isBuyerAuth};

Review.model.js

import mongoose from "mongoose";

const reviewSchema = new mongoose.Schema({  
    user : {
        type : mongoose.Schema.Types.ObjectId,
        ref : "User",
    },
    hostel : {
        type : mongoose.Schema.Types.ObjectId,
        ref : "Hostel",
    },
    rating : {
        type : Number,
        required : true,
        min : 1,
        max : 5,
    },
    comment : {
        type : String,
        required : true,
        maxLength : 500,
    },
    datePosted : {
        type : Date,
        default : Date.now,
    },
}, {timestamps : true});

export const Review = new mongoose.model("Review", reviewSchema);

review.routes.js

import {Router} from "express";
import { postReviews, getAllReviewsForHostel } from "../controllers/reviews.controllers.js";
import { isBuyerAuth } from "../middlewares/user.isBuyer.middleware.js";
import { verifyUser } from "../middlewares/user.auth.middleware.js";

const router = Router();

router.route("/post-reviews/:id").post(verifyUser, isBuyerAuth, postReviews);

router.route("/get-all-reviews/:id").get(verifyUser, getAllReviewsForHostel);


export default router;

app.js

import express from 'express';
import cors from 'cors';
import userRouter from './routes/user.routes.js';
import hostelRouter from './routes/hostel.routes.js';
import reviewRouter from './routes/review.routes.js';
import bookmarkRouter from './routes/bookmark.routes.js';
import cookieParser from 'cookie-parser';

const app = express();

const allowedOrigins = ['http://localhost:5174']; // Specify your frontend origin

const corsOptions = {
  origin: allowedOrigins,
  credentials: true, // This is required to allow cookies with CORS
};

app.use(cors(corsOptions));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

app.use('/api/v1/users', userRouter);
app.use('/api/v1/hostels', hostelRouter);
app.use('/api/v1/reviews', reviewRouter);
app.use('/api/v1/bookmarks', bookmarkRouter);

export default app;

I wanted to make sure that when user(Buyer) comes to the page of singleHostel he see the info of hostel and there is an option to post review for that hostel.

I tried testing the postReview using postman so there the review is getting posted successfully but when I try to do it with frontend form it givves me the error.


Solution

  • Backend most probably. console.log the error in the backend in catch block to debug further.