Tengo un modelo llamado Product :
class Product { constructor(title, price, description, imageUrl) { this.title = title; this.price = price; this.description = description; this.imageUrl = imageUrl; } save() { const db = getDb(); return db.collection("products").insertOne(this) .catch(error => dbDebugger(error)); } static fetchById(productId) { const db = getDb(); return db.collection("products").findOne({ _id: new ObjectId(productId) }) .catch(error => dbDebugger(error.message)); } } y en uno de mis controladores traté de encontrar el producto con el productId de producto que provendrá de la url como un parámetro de url:
exports.getSingleProduct = (req, res) => { const productId = req.params.id; Product.fetchById(productId) .then(product => { if(!product) { return res.redirect("404"); } res.render("product-detail", { product, pageTitle: "Product Detail" }); }) .catch(error => dbDebugger(error)); }; y de hecho todo funciona sin ningún problema. pero una vez que cambie el productId de url (como agregarle una letra), veré un error (aunque debería poder manejarlo en mi controlador).
BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer Creo que el error proviene de mi modelo una vez que intenté convertirlo a ObjectId , si es así, ¿cómo puedo solucionarlo? y si no es así, ¿de dónde viene ese error?
Su error ocurre antes de que comience cualquier código asíncrono y .catch() solo se usa para manejar promesas rechazadas.
Recomendaría usar funciones async en su lugar, que tratarán las fallas síncronas y asíncronas de la misma manera.
static async fetchById(productId) { const db = getDb(); try { return await db.collection("products") .findOne({ _id: new ObjectId(productId) }); } catch (error) { dbDebugger(error.message); throw error; // don't forget to keep the promise rejection going } }Este error ocurre cuando intenta convertir un valor no válido en ObjectId , no estoy familiarizado con mongoose fetchById , asumo que es una función personalizada que usted o su equipo escribieron donde lanzan el _id en ObjectId ,
Supongo que el código se parece un poco a esto:
fetchById(id){ return this.model.findOne({_id: new ObjectId(id)}) } Esta es la razón por la que cuando corrompe manualmente la cadena de objectid, se convierte en un objectid no válido, y cuando ocurre la conversión, arroja un error. Personalmente, recomendaría agregar validación a la ruta REST para asegurarse de que param.id sea realmente un ObjectId válido.