hoangvvo / next-connect

The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2

Home Page:https://www.npmjs.com/package/next-connect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

unexpectedly enters the If statement in a middleware and sends error

perinazzoo opened this issue · comments

Nextjs version: 12.3.0
Next-connect version: 0.13.0 (tried the v1 but got more errors because of the database connection)

Problem:

Tried to make a middleware that tests a regexp to make sure the query string matches the expected structure, but when I call the API it toggles between the error message and the successful message.

i.e. it enters the if statement and another time it leaves the middleware and goes through the request with the same query string

If the query string is wrong, the response will be always error, my problem is when the query string is correct

Expected:

The response to be always success when the query string matches the pattern and the response to be always error when the query string does not match the pattern

Got:

Response toggle between error and success when the query string matches the pattern and the response is always error when the query string does not match the pattern

@/backend/middlewares/query-fields.ts

import { NextApiResponse } from 'next'
import { NextHandler } from 'next-connect'

const fieldsExpectedPattern = new RegExp(/^-?[a-zA-Z]+(,-?[a-zA-Z]+)*$/g)

export function queryFieldsMiddleware(req: CustomNextApiRequest, res: NextApiResponse, next: NextHandler) {
  if (req.query.fields && Array.isArray(req.query.fields)) {
    req.query.fields = req.query.fields.join(',')
  }

  if (req.query.fields && !fieldsExpectedPattern.test(req.query.fields.trim())) {
    res.status(400).json({
      message: 'got it bro'
    })
    return
  }

  if (!req.query.fields) {
    req.fields = ''
  }

  if (req.query.fields) {
    req.fields = req.query.fields?.replaceAll(',', ' ')
  }

  next()
}

@/pages/api/products/[id].ts

import Handler from '@/backend/helpers/handler'
import { queryFieldsMiddleware } from '@/backend/middlewares/query-fields'
import Product from '@/backend/models/Product'

const handler = Handler.createHandler()

handler.use(queryFieldsMiddleware)

handler.get(async (req, res) => {
  const { id } = req.query
  const projection = req.fields ?? ''

  const product = await Product.findOne(
    {
      _id: id
    },
    projection
  )

  res.json(product)
})

export default handler

@/backend/helpers/handler.ts

import mongoose, { Mongoose } from 'mongoose'
import { NextApiRequest, NextApiResponse } from 'next'
import nextConnect, { NextHandler } from 'next-connect'

class Handler {
  static dbConnection: null | Mongoose = null

  static async dbMiddleware(_: NextApiRequest, res: NextApiResponse, next: NextHandler) {
    try {
      if (!Handler.dbConnection) {
        Handler.dbConnection = (await mongoose.connect(String(process.env.MONGO_URL))) as unknown as Mongoose
      }
      next()
    } catch (err) {
      console.error('Database connection error: \n', err)
      return res.status(500).json({
        message: 'Internal server error'
      })
    }
  }

  public createHandler() {
    return nextConnect<CustomNextApiRequest, NextApiResponse>({
      attachParams: true,
      onNoMatch(_, res) {
        return res.status(404).send(undefined)
      }
    }).use(Handler.dbMiddleware)
  }
}

export default new Handler()

Closing the issue because I found it was related to Nextjs and found a fix:

Fix: Changing the RegExp declaration to the middleware function scope fixed the issue.