Why am I getting can't set Header after they are sent in this case?

exports.checkTokenMW = async (req, res, next) => {
  try{  
    const token = req.cookies["access"]   
    const authData = await this.verifyAccessToken(token);
    console.log(authData, "checkingTokenmw")   
     res.json(authData)
  }catch(err){     
    res.status(401);
  }
  next()
};

exports.verifyAccessToken = async (accessToken) => {  
  return new Promise((resolve, reject) => {    
    jwt.verify(accessToken, keys.accessTokenSecret, (err, authData) => {          
      if(err){
        console.log(err)
        return reject(createError.Unauthorized()); 
      }
      console.log(authData, "accesstoken")
     return resolve(authData);   
    });
  })
};

exports.verifyRefreshToken = async (refreshToken, res) => {
  return new Promise((resolve, reject) =>{
    //const refreshToken = req.body.refreshToken;
    
    jwt.verify(refreshToken, keys.refreshTokenSecret, (err, authData) =>{
      if (err) { reject(createError.Unauthorized()); return }      
      const userId = authData.userId
      return resolve(userId)
    })
  })
};

exports.logOut = async (req, res) => {
  try{
      console.log("----------- logout")
      const refreshToken = req.cookies["refresh"];     
      if(!refreshToken) {throw createError.BadRequest();}
      const user =  await this.verifyRefreshToken(refreshToken);     
       res.clearCookie("refresh")
       res.clearCookie("access")

      res.sendStatus(204);
      res.redirect("/");

      return res.send()
  }catch(err){   
    console.log(err)
  }
};

**The routes file has code something like this **

app.get('/api/logout', authService.checkTokenMW,authService.logOut)

I have been trying to tackle this error from a while not exactly sure what header is setting itself multiple times

**Here is the error **

**

>     Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
>         at ServerResponse.setHeader (_http_outgoing.js:561:11)
>         at ServerResponse.header (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:771:10)
>         at ServerResponse.append (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:732:15)
>         at ServerResponse.res.cookie (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:857:8)
>         at ServerResponse.clearCookie (E:\COURSE-WEBSITE\main-backend\wiz_backend\node_modules\express\lib\response.js:804:15)
>         at exports.logOut (E:\COURSE-WEBSITE\main-backend\wiz_backend\controllers\auth-controller.js:131:13)
>         at processTicksAndRejections (internal/process/task_queues.js:95:5) {
>       code: 'ERR_HTTP_HEADERS_SENT'
>     }

**


Solution 1:

The problem is inside the middleware function. Once you check for authData you don't need to send it back to response using res.json(authData). Because after that response will be sent and your next() function will be triggered anyways. Since next() will be called your route handler will try to also send another response which is the conflict you face. At the same time, in catch block, you need to have a return statement, so the function execution will be stopped, and it will not reach till next()

exports.checkTokenMW = async (req, res, next) => {
  try{  
    const token = req.cookies["access"]   
    const authData = await this.verifyAccessToken(token);
    console.log(authData, "checkingTokenmw")   
    // res.json(authData) // <- remove this line
  }catch(err){     
    return res.status(401); // <- here
  }
  next()
};