[Error] MongooseError: Model.findOne() no longer accepts a callback

changheeee·2023년 10월 10일
0

오류

"Model.prototype.findOne()는 더이상 콜백을 허용하지 않습니다"라는 에러가 발생했습니다.


해결

Mongoose6 이전에는 Model.findOne()에 콜백을 통해 비동기 작업이 완료될 때 실행되도록 할 수 있었으나, 현재 Mongoose 버전인 Mongoose7에서는 더이상 콜백을 허용하지 않으며, 항상 Promise를 반환하도록 해야합니다.

Mongoose7 콜백 지원 중단 함수는 아래 공식문서에서 확인 가능합니다
https://mongoosejs.com/docs/migrating_to_7.html#dropped-callback-support

🚫🚫 수정 전 (콜백방식)

app.post('/login', (req, res) => {
    // 요청된 이메일이 DB에 있는지 조회
    User.findOne({ email: req.body.email }, (err, user) => {
        if (!user) {
            return res.json({
                loginSuccess: false,
                message: "제공된 이메일에 해당하는 유저가 없습니다."
            })
        }
        // 해당 이메일이 있다면 비밀번호가 맞는지 확인
        user.comparePassword(req.body.password, (err, isMatch) => {
            if (!isMatch)
                return res.json({
                    loginSuccess: false,
                    message: "비밀번호가 틀렸습니다."
                })
            // 비밀번호 확인되면 토큰 생성
        })
    })
})

🔨🔨 수정 후 (Promise 방식)

app.post('/api/users/login', async (req, res) => {
    try {
        const user = await User.findOne({ email: req.body.email })
        if (!user) {
            return res.json({
                loginSuccess: false,
                message: "제공된 이메일에 해당하는 유저가 없습니다."
            })
        }
        const isMatch = await user.comparePassword(req.body.password)
        console.log(isMatch)
        if (!isMatch) {
            return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })
        }
        const token = await user.generateToken()
        res.cookie("user_auth", token).status(200).json({ loginSuccess: true, userId: user._id })
    } catch (err) {
        return res.status(400).send(err)
    }
})

이전 코드에서는 비동기 작업을 콜백 함수를 사용하여 처리했지만, 수정된 코드에서는 async/await 및 Promise를 사용하여 비동기 작업을 더 간결하게 처리했습니다. 특히, 비밀번호 확인 부분에 대한 변경을 살펴보겠습니다.


//이전 코드 (콜백 방식)
user.comparePassword(req.body.password, (err, isMatch) => {
    if (!isMatch)
        return res.json({
            loginSuccess: false,
            message: "비밀번호가 틀렸습니다."
        })
})
//수정된 코드 (Promise 방식)
const isMatch = await user.comparePassword(req.body.password)
if (!isMatch) {
    return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })
}

여기에서 변경된 부분
user.comparePassword(req.body.password)호출 방식입니다. 이전 코드에서는 이 부분이 콜백 함수를 사용하여 실행되었지만, 수정된 코드에서는 await 키워드를 사용하여 user.comparePassword 메서드를 호출하고, 해당 메서드가 Promise를 반환하도록 변경되었습니다.


깃허브

movie-app

0개의 댓글