Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

insertMany return blank if all inserted docs is error (duplicated error) but not if one insertable item to return validation error #7822

Closed
eisenhaus335 opened this issue May 20, 2019 · 5 comments
Labels
needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity

Comments

@eisenhaus335
Copy link

When i insert docs with everything is duplicated items i got blank response
its really just give me this response [] (from console.log)

But when i give one something insertable. Its give me this response

{
    "result": {
        "ok": 1,
        "n": 1,
        "opTime": {
            "ts": "6693001219876585484",
            "t": 16
        }
    },
    "ops": [
        {
            "_id": "5ce2512c3dfc5d1704812804",
            "sku": "test15",
            "name": "barang",
            "qty": 20,
            "type": "pcs",
            "__v": 0
        }
    ],
    "insertedCount": 1,
    "insertedIds": {
        "0": "5ce2512c3dfc5d1704812804"
    },
    "mongoose": {
        "validationErrors": [
            {
                "errors": {
                    "sku": {
                        "message": "SKU already exists",
                        "name": "ValidatorError",
                        "properties": {
                            "message": "SKU already exists",
                            "type": "user defined",
                            "path": "sku",
                            "value": "test11"
                        },
                        "kind": "user defined",
                        "path": "sku",
                        "value": "test11"
                    }
                },
                "_message": "product validation failed",
                "message": "product validation failed: sku: SKU already exists",
                "name": "ValidationError"
            }
        ]
    }
}
const Product = require('../models/product')

async function add(ctx, next) {
    await Product.insertMany(ctx.request.body, { ordered: false, rawResult: true })
        .then(function (result) {
            console.log(result)
            ctx.body = {
                ...result
            }
        })
        .catch(function (err) {
            console.log(err)
            ctx.throw(401, 'something is wrong')
        })
}

PS: SKU is unique

Node.js: v12.2.0
"mongoose": "^5.5.9"
Mongodb: 4.0.9

@eisenhaus335 eisenhaus335 changed the title insertMany return blank if all inserted docs is error (duplicated error) but not if only need one to return validation error insertMany return blank if all inserted docs is error (duplicated error) but not if one insertable item to return validation error May 20, 2019
@vkarpov15
Copy link
Collaborator

What does your schema look like? Also, can you please post the custom validator that's reporting the 'SKU already exists' message?

@vkarpov15 vkarpov15 added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label May 26, 2019
@eisenhaus335
Copy link
Author

eisenhaus335 commented May 27, 2019

const mongoose = require('mongoose')

const CreatedSchema = new mongoose.Schema({
    user: {
        type: mongoose.Schema.ObjectId,
        ref: 'user'
    },
    time: { type: Date, default: Date.now() }
}, { _id: false })
const QtySchema = new mongoose.Schema({
    location: {
        type: mongoose.Schema.ObjectId,
        ref: 'location'
    },
    value: Number
}, { _id: false })
const ProductSchema = new mongoose.Schema({
    sku: {
        type: String,
        index: true,
        unique: true, 
        required: true
    },
    name: String,
    qty: [QtySchema],
    type: String,
    created_by: [CreatedSchema]
})

ProductSchema.path('sku').validate(async (value) => {
    const SKUCount = await mongoose.models.product.countDocuments({ sku: value });
    return !SKUCount;
}, 'SKU already exists');

module.exports = mongoose.model('product', ProductSchema)

I though this was intended cause you said " but if ordered is not set (true by default) we should fall back to the current behavior."
#5698 (review)

I think there is nothing wrong from my code except this behaviour is intended as this cause the link I ref to

@vkarpov15
Copy link
Collaborator

I'm still not sure I understand the issue here. I'm guessing you have an issue with insertMany() throwing a validation error and not inserting any docs if there's a duplicate sku number?

@Elyx0
Copy link

Elyx0 commented Jun 5, 2019

The problem seem to arise when it hits the quick escape

    // We filter all failed pre-validations by removing nulls
    const docAttributes = docs.filter(function(doc) {
      return doc != null;
    });
    // Quickly escape while there aren't any valid docAttributes
    if (docAttributes.length < 1) {
      callback(null, []);
      return;
    }

At this step all the information about the validationErrors array defined above are dropped even if the array is not empty but docs is.

I recomment exiting with res.mongoose set like a few lines below. This seems like a leftover from #5337 and #6228

@vkarpov15
Copy link
Collaborator

I'm going to close this issue and lock it, I haven't seen anything even remotely coherent in this thread. Please open up a separate issue with detailed code samples.

@Automattic Automattic locked as spam and limited conversation to collaborators Jun 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity
Projects
None yet
Development

No branches or pull requests

3 participants