sourcetip

Mongoose Error - "users.findOne()" 작업 버퍼링이 10000ms 이후에 시간 초과됨

fileupload 2023. 5. 3. 21:40
반응형

Mongoose Error - "users.findOne()" 작업 버퍼링이 10000ms 이후에 시간 초과됨

코드가 처음에는 작동했지만 왜 작동을 멈추고 다음 오류가 발생했는지 알 수 없습니다.

MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
    at Timeout.<anonymous> (/Users/nishant/Desktop/Yourfolio/backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:184:20)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7)

JWT로 로그인하여 사용자 인증을 시도하고 있습니다.클라이언트는 정상적으로 실행되지만 백엔드에서 이 오류가 발생합니다.내 백엔드 코드:

import neuron from '@yummyweb/neuronjs'
import bodyParser from 'body-parser'
import cors from 'cors'
import mongoose from 'mongoose'
import emailValidator from 'email-validator'
import passwordValidator from 'password-validator'
import User from './models/User.js'
import Portfolio from './models/Portfolio.js'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import auth from './utils/auth.js'

// Dot env
import dotenv from 'dotenv'
dotenv.config()

// Custom Password Specifications
// Username Schema
const usernameSchema = new passwordValidator()
usernameSchema.is().min(3).is().max(18).is().not().spaces()

// Password Schema
const passwordSchema = new passwordValidator()
passwordSchema.is().min(8).is().max(100).has().uppercase().has().lowercase().has().digits().is().not().spaces()

const PORT = process.env.PORT || 5000
const neuronjs = neuron()

// Middleware
neuronjs.use(bodyParser())
neuronjs.use(cors())

// Mongoose Connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true }, () => console.log("MongoDB Connected"))

// API Routes
neuronjs.POST('/api/auth/signup', async (req, res) => {
    const { username, email, password, passwordConfirmation } = req.body

    // Validation: all fields are filled
    if (!username || !email || !password || !passwordConfirmation) {
        return res.status(400).json({ 
            "error": "true",
            "for": "fields",
            "msg": "fill all the fields"
        })
    }

    // Validation: username is valid
    if (usernameSchema.validate(username, { list: true }).length !== 0) {
        return res.status(400).json({ 
            "error": "true",
            "for": "username",
            "method_fail": usernameSchema.validate(username, { list: true }),
            "msg": "username is invalid"
        })
    }

    // Validation: email is valid
    if (!emailValidator.validate(email)) {
        return res.status(400).json({ 
            "error": "true",
            "for": "email",
            "msg": "email is invalid"
        })
    }

    // Validation: password is valid
    if (passwordSchema.validate(password, { list: true }).length !== 0) {
        return res.status(400).json({ 
            "error": "true",
            "for": "password",
            "method_fail": passwordSchema.validate(password, { list: true }),
            "msg": "password is invalid"
        })
    }

    // Validation: password is confirmed
    if (password !== passwordConfirmation) {
        return res.status(400).json({ 
            "error": "true",
            "for": "confirmation",
            "msg": "confirmation password needs to match password"
        })
    }

    // Check for existing user with email
    const existingUserWithEmail = await User.findOne({ email })
    if (existingUserWithEmail)
        return res.status(400).json({ "error": "true", "msg": "a user already exists with this email" })

    // Check for existing user with username
    const existingUserWithUsername = await User.findOne({ username })
    if (existingUserWithUsername)
        return res.status(400).json({ "error": "true", "msg": "a user already exists with this username" })

    // Generating salt
    const salt = bcrypt.genSalt()
    .then(salt => {
        // Hashing password with bcrypt
        const hashedPassword = bcrypt.hash(password, salt)
        .then(hash => {
            const newUser = new User({
                username,
                email,
                password: hash
            })
            // Saving the user
            newUser.save()
            .then(savedUser => {
                const newPortfolio = new Portfolio({
                    user: savedUser._id,
                    description: "",
                    socialMediaHandles: {
                        github: savedUser.username,
                        dribbble: savedUser.username,
                        twitter: savedUser.username,
                        devto: savedUser.username,
                        linkedin: savedUser.username,
                    }
                })

                // Save the portfolio
                newPortfolio.save()

                // Return the status code and the json
                return res.status(200).json({
                    savedUser
                })
            })
            .catch(err => console.log(err))
        })
        .catch(err => console.log(err))
    })
    .catch(err => console.log(err))
})

neuronjs.POST('/api/auth/login', async (req, res) => {
    try {
        const { username, password } = req.body

        // Validate
        if (!username || !password) {
            return res.status(400).json({ "error": "true", "msg": "fill all the fields", "for": "fields", })
        }

        const user = await User.findOne({ username })
        if (!user) {
            return res.status(400).json({ "error": "true", "msg": "no account is registered with this username", "for": "username" })
        }
    
        // Compare hashed password with plain text password
        const match = await bcrypt.compare(password, user.password)
    
        if (!match) {
            return res.status(400).json({ "error": "true", "msg": "invalid credentials", "for": "password" })
        }
    
        // Create JWT token
        const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET)
        return res.json({ token, user: { "id": user._id, "username": user.username, "email": user.email } })
    }
    catch (e) {
        console.log(e)
    }
})

// Delete a user and their portfolio
neuronjs.DELETE("/api/users/delete", async (req, res) => {
    auth(req, res)
    const deletedPortfolio = await Portfolio.findOneAndDelete({ user: req.user })
    const deletedUser = await User.findByIdAndDelete(req.user)
    res.json(deletedUser)
})

neuronjs.POST("/api/isTokenValid", async (req, res) => {
    const token = req.headers["x-auth-token"]
    if (!token) return res.json(false)
    
    const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
    if (!verifiedToken) return res.json(false)
    
    const user = await User.findById(verifiedToken.id)
    if (!user) return res.json(false)

    return res.json(true)
})

// Getting one user
neuronjs.GET("/api/users/user", async (req, res) => {
    auth(req, res)
    const user = await User.findById(req.user)
    res.json({
        "username": user.username,
        "email": user.email,
        "id": user._id
    })
})

// Getting the porfolio based on username
neuronjs.GET("/api/portfolio/:username", async (req, res) => {
    try {
        const existingUser = await User.findOne({ username: req.params.username })
        // User exists
        if (existingUser) {
            const userPortfolio = await Portfolio.findOne({ user: existingUser._id })
            return res.status(200).json(userPortfolio)
        }
        // User does not exist
        else return res.status(400).json({ "error": "true", "msg": "user does not exist" })
    }
    catch (e) {
        console.log(e)
        return res.status(400).json({ "error": "true", "msg": "user does not exist" })
    }
})

// Update Portfolio info
neuronjs.POST("/api/portfolio/update", async (req, res) => {
    auth(req, res)

    // Find the portfolio
    const portfolio = await Portfolio.findOne({ user: req.user })
    // Then, update the portfolio
    if (portfolio) {
        // Call the update method
        const updatedPortfolio = await portfolio.updateOne({
             user: req.user, 
             description: req.body.description, 
             socialMediaHandles: req.body.socialMediaHandles, 
             greetingText: req.body.greetingText, 
             navColor: req.body.navColor, 
             font: req.body.font, 
             backgroundColor: req.body.backgroundColor,
             rssFeed: req.body.rssFeed,
             displayName: req.body.displayName,
             layout: req.body.layout,
             occupation: req.body.occupation
            })
        return res.status(200).json(portfolio)
    }
})

neuronjs.listen(PORT, () => console.log("Server is running on port " + PORT))

auth.js 파일 기능:

import jwt from 'jsonwebtoken'

const auth = (req, res) => {
    const token = req.headers["x-auth-token"]
    if (!token)
        return res.status(401).json({ "error": "true", "msg": "no authentication token" })
    
    const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
    if (!verifiedToken)
        return res.status(401).json({ "error": "true", "msg": "token failed" })
    
    req.user = verifiedToken.id
}

export default auth

도움을 주시면 감사하겠습니다. 이미 node_modules 삭제 및 mongoose 재설치와 같은 몇 가지 솔루션을 시도했습니다.

제 경험으로는 데이터베이스가 연결되어 있지 않을 때 이런 일이 발생합니다. 다음 사항을 확인해 보십시오.

  • 데이터베이스가 연결되어 있고 코드에서 동일한 URL을 가리키고 있습니까?
  • 당신의 신의 합니다.mongoose.connect(...)코드를 로드하는 중입니다.

이 문제에 직면한 것은 운영 환경에서node index.js내 터미널과 몽구스 연결 코드가 다른 파일에 있었습니다.index한 후 .

다음 링크에서 찾을 수 있는 설명서에 따르면, https://mongoosejs.com/docs/connections.html#buffering

Mongoose를 사용하면 MongoDB에 대한 연결을 설정하기 위해 Mongoose를 기다리지 않고 모델을 즉시 사용할 수 있습니다.

mongoose 버퍼 모델 함수가 내부적으로 호출되기 때문입니다.이 버퍼링은 편리하지만 일반적인 혼동의 원인이기도 합니다.연결하지 않고 모델을 사용하는 경우 Mongoose는 기본적으로 오류를 발생시키지 않습니다.

TL;DR:

연결이 설정되기 전에 모델을 호출하는 중입니다.이러한 함수는 Mongoose 5에서 약속을 반환하므로 connect()와 함께 비동기/wait를 사용하거나 createConnection(); 또는 .then()을 사용해야 합니다.

Mongoose 6를 사용할 때도 같은 문제가 있었습니다.다음과 같은 방법으로 index.js 파일의 Mongoose에 연결했습니다.

mongoose.connect(
  process.env.MONGO_URL,
  { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true },
  () => {
    console.log('Connected to MongoDB');
  }
);

Mongoose 6에 대한 다음 정보를 그들의 사이트에서 찾았습니다.

useNewUrlParser, useUnifiedTopology, useFindAndModify 및 useCreateIndex는 더 이상 지원되지 않는 옵션입니다.Mongoose 6은 항상 useNewUrlParser, useUnifiedTopology 및 useCreateIndex가 true이고 useFindAndModify가 false인 것처럼 동작합니다.코드에서 이러한 옵션을 제거하십시오.

가 제가제 했을때를 제거했을 때.useCreateIndex: true문제가 해결된 옵션입니다.

저는 이런 일을 여러 번 겪었습니다. 특히 몽구스가 필요한 중첩 종속성을 업그레이드할 때 말입니다.이것은 항상 저에게 효과가 있습니다.

rm -rf node_modules
rm package-lock.json
npm install --package-lock-only
npm install

제 코드는 한 PC에서 정상적으로 작동했지만 다른 PC에서도 동일한 오류가 발생했습니다.저는 https://www.mongodb.com/ 의 MongoDB 무료 호스팅을 가지고 있습니다.

를 재를 IP추가수정다니에 하였습니다.Security - Network Access - IP Access List호스트 서버에 있습니다.

그 이유는 당신의 db에 대한 IP 주소가 화이트리스트에 올라 있지 않기 때문이라고 생각합니다.이런 문제가 있으면 확인하세요.

허락하다Network Access사방에서

이것은 일시적인 해결책이라는 것을 알아두시기 바랍니다.

이 오류가 말하고자 하는 것은 MongoDB 컬렉션에 액세스할 수 없다는 것입니다.이는 주로 다음 두 가지 때문일 수 있습니다.

  1. IP 주소는 데이터베이스에 액세스할 수 없습니다.
  2. 인터넷에 연결되어 있지 않습니다.

내가 이 코드를 사용한 후에 나에게 효과가 있었습니다.app.js파일 이름:

mongoose.connect(process.env.DATABASE_URI, () => {
    console.log("Mongo connected");
});

그리고 내 코드에서 아래의 네 가지 몽구스 옵션을 모두 제거했습니다.

{
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,  
}

클러스터 생성 후 MongoDB Atlas에서 연결 및 IP 추가 또는 다른 IP 추가를 클릭합니다.

저도 같은 문제가 있었습니다.저의 경우 mongoose.connect 문을 다른 파일에 보관했다가 require 문을 작성하는 동안 호출하는 것을 잊었습니다.

require(./services/mongoose);

나는 index.js 파일에서 이것을 수행했고 이것으로 변경했습니다.

require(./services/mongoose)();

서버에 오류가 발생했을 때 데이터베이스를 사용하려고 했을 때 이 문제가 발생했습니다. 그리고 몽구스가 87개의 거대한 부품 오류 패널을 만들었고, 그렇게 했을 때 몽구스에게 전달한 옵션이 평가 절하되었다는 것을 알게 되었습니다.따라서 서버를 시작하는 위치로 스크롤할 수 있는 경우, 특정 선택사항을 제거하거나 추가하라는 세부사항이 표시될 수 있습니다.추가 옵션을 제거하여 문제에 대한 사진 증거 및 터미널에서 문제를 발견한 위치문제가 해결되었습니다.

다른 네트워크나 IP에서 프로젝트를 실행하려는 경우 mongoDB 아틀라스에서 ip를 화이트리스트에 추가해야 합니다.네트워크 탭 > IP 주소 추가로 이동하기만 하면 됩니다.

이미 내 몽고드 지도책에 만들어진 컬렉션인 클러스터가 있었고, 내가 해야 할 일은 그것을 확인하고 그것이 작동하도록 다른 게시 요청을 보내는 것이었습니다.

MongoDB Atlas에 연결한 후 기능 상단(파일 내부)에서 MongoDB에 연결하고 (CRUD) 작업을 수행하는지 확인합니다.

그게 말이 되기를 바랍니다.파일에서 다른 서버의 데이터를 로드하고 MongoDB 서버에 연결하는 비동기 작업 후 MongoDB에 삽입하기 때문에 오류가 발생했습니다.

정답

await mongoose.connect(MONGO_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
}); 
await parseAndLoadPlanetsData();

잘못됨

await parseAndLoadPlanetsData();
await mongoose.connect(MONGO_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

.env 파일에서 데이터베이스 연결 문자열을 가져오는 경우 .env 파일이 실행 중인 루트 폴더에 있는지 확인합니다.npm run지휘권

저는 여기 있는 모든 해결책을 시도해 보았습니다.갑자기 .env 파일이 /server 폴더에 있다는 것을 깨달았습니다. /server 폴더는 제 프로젝트 루트 폴더보다 한 폴더 더 깊습니다.

이동을 확인합니다..env프로젝트 루트 폴더에 파일!!다음 정보를process.env.DB_CONNECT예를들면.

이 오류[user.findOne()] 표시하는 이유는config패키지 버전이 자동으로 업데이트됩니다.

단말기에 다음을 입력합니다.

npm i -E config@3.3.1

또는

yarn add -E config@3.3.1

mongoose.connect('mongodb://localhost/myapp', {useNewUrlParser: true});

이 추가만 하면 됩니다.{useNewUrlParser: true}연결 파일에 있습니다.

언급URL : https://stackoverflow.com/questions/65408618/mongooseerror-operation-users-findone-buffering-timed-out-after-10000ms

반응형