fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck#75
fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck#75
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…duplicate precheck Agent-Logs-Url: https://github.com/yash-pouranik/urBackend/sessions/a4ebb02d-93e3-4686-9938-d19a6344dc1a Co-authored-by: yash-pouranik <172860064+yash-pouranik@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes two edge cases in the dynamic model injection utilities to prevent unsafe index rollback and improve duplicate detection before creating MongoDB unique indexes.
Changes:
- Make unique-index rollback safe by tracking only indexes newly created during the current
createUniqueIndexesrun. - Adjust required-field duplicate precheck to include documents missing the field (aligning with MongoDB unique-index behavior for missing values).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| throw new Error( | ||
| `Cannot create unique index on '${normalizedKey}'. ${duplicates.length} duplicate values exist.${examples ? ` Examples: ${examples}` : ""}`, | ||
| const existingIndexes = await Model.collection.indexes(); |
There was a problem hiding this comment.
Model.collection.indexes() will throw a NamespaceNotFound (code 26 / "ns not found") error when the collection doesn’t exist yet. createUniqueIndexes is called immediately after compiling a model for newly-created collections (before any inserts), so this can cause schema/collection creation to fail before any indexes are created. Consider wrapping the indexes() call in a try/catch and treating NamespaceNotFound as an empty index list (or ensuring the collection exists via Model.createCollection() / Model.init() before calling indexes()).
| const existingIndexes = await Model.collection.indexes(); | |
| let existingIndexes = []; | |
| try { | |
| existingIndexes = await Model.collection.indexes(); | |
| } catch (err) { | |
| const isNamespaceNotFound = | |
| err && | |
| (err.code === 26 || | |
| err.codeName === "NamespaceNotFound" || | |
| err.message === "ns not found" || | |
| (typeof err.message === "string" && | |
| err.message.toLowerCase().includes("ns not found"))); | |
| if (!isNamespaceNotFound) { | |
| throw err; | |
| } | |
| } |
Two edge-case bugs in
createUniqueIndexesandgetUniqueFieldFilterthat could cause silent data loss and missed duplicate detection on live collections.Changes
createUniqueIndexes): Snapshot existing index names before the loop; only push indexes intocreatedIndexesif they weren't already present. The rollback path now exclusively drops indexes created by the current operation, preventing accidental destruction of pre-existing indexes when a later field fails.getUniqueFieldFilter): For required fields, return{}instead of{ [fieldKey]: { $exists: true } }. MongoDB's unique index treats all missing-field documents as duplicatenulls, so the old filter could pass the precheck whilecreateIndexstill throws error 11000.