Search code examples
node.jsmongodberror-handlingconstructorcallback

Why am I getting this error: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters


I want to log out an error if a particular task id is not found in the database. With the code I have written, I can get a task with a correct id but I get a bug when I use a wrong id instead of logging my custom error, I get this error:

Error:   messageFormat: undefined,
  stringValue: '"65cf79f286f0b32a7022ed9p"',
  kind: 'ObjectId',
  value: '65cf79f286f0b32a7022ed9p',
  path: '_id',
  reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters

If I use a wrong id, the "IF" statement is not read and my code crashes. Here is my code:

const getTask = asyncWrapper(async(req, res, next) =>{
        const {id:taskID} = req.params
        const task = await Task.findOne({_id: taskID})
        if(!task){
            console.log("Hit!")
            const error = new Error('Not Found')
            error.status = 404
            return next(error)
  
        }
        res.status(200).json({task})
})

This is my error handler:

const errorHandlerMiddleware =(err, req, res, next)=>{
    console.log(err)
    return res.status(500).json({msg: "something went wrong, try again"})
}

module.exports = errorHandlerMiddleware


this is my app file:

//middleware
app.use(express.static("./public"))
app.use(express.json())

//routes
// app.get("/hello", (req, res)=>{
//     res.send("Task Manager App")
// })
app.use("/api/v1/tasks", tasks)
app.use(notFound)
app.use(errorHandlerMiddleware)

const port = 3000

const start = async() =>{
    try {
        await connectDB(process.env.MONGO_URI)
        app.listen(port, console.log(`app is listening on server ${port}...`))

    } catch (error) {
        console.log(error)
    }
}
start()


Solution

  • Use a simple try catch when parsing your taskId.

    In your example, you get an error because the string provided is not an hex value (as said VLAZ in comment).

    const getTask = asyncWrapper(async(req, res, next) =>{
            try {
            const {id:taskID} = req.params
            const task = await Task.findOne({_id: taskID})
            if(!task){
                console.log("Hit!")
                const error = new Error('Not Found')
                error.status = 404
                return next(error)
      
            }
            res.status(200).json({task})
            } catch (parseError) {
                const error = new Error('Error while parsing taskId in ObjectId')
                error.status = 404
                return next(error)
            }
    })