@zodmon/core 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -99,6 +99,245 @@ function createExpressionBuilder() {
99
99
  };
100
100
  }
101
101
 
102
+ // src/errors/wrap.ts
103
+ import { MongoBulkWriteError, MongoNetworkError, MongoServerError } from "mongodb";
104
+
105
+ // src/errors/base.ts
106
+ var ZodmonError = class extends Error {
107
+ name = "ZodmonError";
108
+ /** The MongoDB collection name associated with this error. */
109
+ collection;
110
+ /** The underlying error that caused this error, if any. */
111
+ cause;
112
+ constructor(message, collection2, options) {
113
+ super(message);
114
+ this.collection = collection2;
115
+ if (options?.cause) {
116
+ this.cause = options.cause;
117
+ }
118
+ }
119
+ };
120
+
121
+ // src/errors/auth.ts
122
+ var ZodmonAuthError = class extends ZodmonError {
123
+ name = "ZodmonAuthError";
124
+ /** The MongoDB error code (13 or 18). */
125
+ code;
126
+ constructor(collection2, code, cause) {
127
+ const message = code === 18 ? `Authentication failed for "${collection2}": check connection credentials` : `Not authorized to perform this operation on "${collection2}"`;
128
+ super(message, collection2, { cause });
129
+ this.code = code;
130
+ }
131
+ };
132
+
133
+ // src/errors/bulk-write.ts
134
+ var ZodmonBulkWriteError = class extends ZodmonError {
135
+ name = "ZodmonBulkWriteError";
136
+ /** Number of documents successfully inserted. */
137
+ insertedCount;
138
+ /** Number of documents matched by update filters. */
139
+ matchedCount;
140
+ /** Number of documents actually modified. */
141
+ modifiedCount;
142
+ /** Number of documents deleted. */
143
+ deletedCount;
144
+ /** Individual write errors with their operation index, code, and message. */
145
+ writeErrors;
146
+ constructor(collection2, cause, totalOps) {
147
+ const bulkErr = cause;
148
+ const result = bulkErr["result"] ?? {};
149
+ const rawErrors = bulkErr["writeErrors"] ?? [];
150
+ const writeErrors = rawErrors.map((e) => ({
151
+ index: e["index"] ?? 0,
152
+ code: e["code"] ?? 0,
153
+ message: e["errmsg"] ?? e["message"] ?? "unknown error"
154
+ }));
155
+ const failedMsg = totalOps !== void 0 ? `${writeErrors.length} of ${totalOps} operations failed` : `${writeErrors.length} operations failed`;
156
+ super(`Bulk write failed on "${collection2}": ${failedMsg}`, collection2, { cause });
157
+ this.insertedCount = result["insertedCount"] ?? 0;
158
+ this.matchedCount = result["matchedCount"] ?? 0;
159
+ this.modifiedCount = result["modifiedCount"] ?? 0;
160
+ this.deletedCount = result["deletedCount"] ?? 0;
161
+ this.writeErrors = writeErrors;
162
+ }
163
+ };
164
+
165
+ // src/errors/doc-validation.ts
166
+ var ZodmonDocValidationError = class extends ZodmonError {
167
+ name = "ZodmonDocValidationError";
168
+ /** Server-provided validation failure details. */
169
+ errInfo;
170
+ constructor(collection2, errInfo, cause) {
171
+ super(
172
+ `Server-side document validation failed for "${collection2}": ${cause.message}`,
173
+ collection2,
174
+ { cause }
175
+ );
176
+ this.errInfo = errInfo;
177
+ }
178
+ };
179
+
180
+ // src/errors/duplicate-key.ts
181
+ var INDEX_REGEX = /index:\s+(\S+)/;
182
+ var DUP_KEY_FIELD_REGEX = /dup key:\s*\{\s*(\w+):/;
183
+ var ZodmonDuplicateKeyError = class extends ZodmonError {
184
+ name = "ZodmonDuplicateKeyError";
185
+ /** The first field that caused the duplicate key violation. */
186
+ field;
187
+ /** The duplicate value, or `undefined` if it could not be extracted. */
188
+ value;
189
+ /** The name of the index that was violated. */
190
+ index;
191
+ /** The key pattern of the violated index (e.g. `{ email: 1 }`). */
192
+ keyPattern;
193
+ /** The key values that caused the violation. */
194
+ keyValue;
195
+ constructor(collection2, cause) {
196
+ const serverErr = cause;
197
+ const kp = serverErr["keyPattern"];
198
+ const kv = serverErr["keyValue"];
199
+ let field;
200
+ let value;
201
+ let keyPattern;
202
+ let keyValue;
203
+ if (kp && kv) {
204
+ const firstKey = Object.keys(kp)[0] ?? "unknown";
205
+ field = firstKey;
206
+ value = kv[firstKey];
207
+ keyPattern = kp;
208
+ keyValue = kv;
209
+ } else {
210
+ const fieldMatch = cause.message.match(DUP_KEY_FIELD_REGEX);
211
+ field = fieldMatch?.[1] ?? "unknown";
212
+ value = void 0;
213
+ keyPattern = field !== "unknown" ? { [field]: 1 } : {};
214
+ keyValue = {};
215
+ }
216
+ const indexMatch = cause.message.match(INDEX_REGEX);
217
+ const index2 = indexMatch?.[1] ?? "unknown";
218
+ const valueStr = typeof value === "string" ? `"${value}"` : String(value);
219
+ super(
220
+ `Duplicate key in "${collection2}": ${field} = ${valueStr} (index: ${index2})`,
221
+ collection2,
222
+ { cause }
223
+ );
224
+ this.field = field;
225
+ this.value = value;
226
+ this.index = index2;
227
+ this.keyPattern = keyPattern;
228
+ this.keyValue = keyValue;
229
+ }
230
+ };
231
+
232
+ // src/errors/index-error.ts
233
+ var ZodmonIndexError = class extends ZodmonError {
234
+ name = "ZodmonIndexError";
235
+ /** The MongoDB error code (67, 85, or 86). */
236
+ code;
237
+ constructor(collection2, code, errmsg, cause) {
238
+ const prefix = code === 67 ? "Cannot create index" : code === 85 ? "Index options conflict" : "Index key specs conflict";
239
+ super(`${prefix} on "${collection2}": ${errmsg}`, collection2, { cause });
240
+ this.code = code;
241
+ }
242
+ };
243
+
244
+ // src/errors/network.ts
245
+ var ZodmonNetworkError = class extends ZodmonError {
246
+ name = "ZodmonNetworkError";
247
+ constructor(collection2, cause) {
248
+ super(`Network error on "${collection2}": ${cause.message}`, collection2, { cause });
249
+ }
250
+ };
251
+
252
+ // src/errors/query.ts
253
+ var ZodmonQueryError = class extends ZodmonError {
254
+ name = "ZodmonQueryError";
255
+ /** The MongoDB error code (2, 9, or 292). */
256
+ code;
257
+ constructor(collection2, code, errmsg, cause) {
258
+ const message = code === 292 ? `Query exceeded memory limit on "${collection2}": enable allowDiskUse for large sorts or aggregations` : code === 9 ? `Failed to parse query on "${collection2}": ${errmsg}` : `Bad value in query on "${collection2}": ${errmsg}`;
259
+ super(message, collection2, { cause });
260
+ this.code = code;
261
+ }
262
+ };
263
+
264
+ // src/errors/timeout.ts
265
+ var ZodmonTimeoutError = class extends ZodmonError {
266
+ name = "ZodmonTimeoutError";
267
+ /** The MongoDB error code (50 or 262). */
268
+ code;
269
+ constructor(collection2, code, cause) {
270
+ super(`Operation timed out on "${collection2}": exceeded server time limit`, collection2, {
271
+ cause
272
+ });
273
+ this.code = code;
274
+ }
275
+ };
276
+
277
+ // src/errors/write-conflict.ts
278
+ var ZodmonWriteConflictError = class extends ZodmonError {
279
+ name = "ZodmonWriteConflictError";
280
+ constructor(collection2, cause) {
281
+ super(
282
+ `Write conflict in "${collection2}": another operation modified this document concurrently \u2014 retry the transaction`,
283
+ collection2,
284
+ { cause }
285
+ );
286
+ }
287
+ };
288
+
289
+ // src/errors/wrap.ts
290
+ function wrapMongoError(err, collection2) {
291
+ if (err instanceof ZodmonError) {
292
+ throw err;
293
+ }
294
+ if (err instanceof MongoBulkWriteError) {
295
+ throw new ZodmonBulkWriteError(collection2, err);
296
+ }
297
+ if (err instanceof MongoNetworkError) {
298
+ throw new ZodmonNetworkError(collection2, err);
299
+ }
300
+ if (err instanceof MongoServerError) {
301
+ switch (err.code) {
302
+ case 11e3:
303
+ case 11001:
304
+ throw new ZodmonDuplicateKeyError(collection2, err);
305
+ case 112:
306
+ throw new ZodmonWriteConflictError(collection2, err);
307
+ case 50:
308
+ case 262:
309
+ throw new ZodmonTimeoutError(collection2, err.code, err);
310
+ case 13:
311
+ case 18:
312
+ throw new ZodmonAuthError(collection2, err.code, err);
313
+ case 67:
314
+ case 85:
315
+ case 86:
316
+ throw new ZodmonIndexError(collection2, err.code, err.message, err);
317
+ case 2:
318
+ case 9:
319
+ case 292:
320
+ throw new ZodmonQueryError(collection2, err.code, err.message, err);
321
+ case 121:
322
+ throw new ZodmonDocValidationError(
323
+ collection2,
324
+ err.errInfo,
325
+ err
326
+ );
327
+ default:
328
+ throw new ZodmonError(`MongoDB error on "${collection2}": ${err.message}`, collection2, {
329
+ cause: err
330
+ });
331
+ }
332
+ }
333
+ if (err instanceof Error) {
334
+ throw new ZodmonError(`Unexpected error on "${collection2}": ${err.message}`, collection2, {
335
+ cause: err
336
+ });
337
+ }
338
+ throw new ZodmonError(`Unexpected error on "${collection2}": ${String(err)}`, collection2);
339
+ }
340
+
102
341
  // src/schema/ref.ts
103
342
  import { z } from "zod";
104
343
  var refMetadata = /* @__PURE__ */ new WeakMap();
@@ -184,8 +423,12 @@ var AggregatePipeline = class _AggregatePipeline {
184
423
  * ```
185
424
  */
186
425
  async toArray() {
187
- const cursor = this.nativeCollection.aggregate(this.stages);
188
- return await cursor.toArray();
426
+ try {
427
+ const cursor = this.nativeCollection.aggregate(this.stages);
428
+ return await cursor.toArray();
429
+ } catch (err) {
430
+ wrapMongoError(err, this.definition.name);
431
+ }
189
432
  }
190
433
  /**
191
434
  * Stream pipeline results one document at a time via `for await...of`.
@@ -200,9 +443,13 @@ var AggregatePipeline = class _AggregatePipeline {
200
443
  * ```
201
444
  */
202
445
  async *[Symbol.asyncIterator]() {
203
- const cursor = this.nativeCollection.aggregate(this.stages);
204
- for await (const doc of cursor) {
205
- yield doc;
446
+ try {
447
+ const cursor = this.nativeCollection.aggregate(this.stages);
448
+ for await (const doc of cursor) {
449
+ yield doc;
450
+ }
451
+ } catch (err) {
452
+ wrapMongoError(err, this.definition.name);
206
453
  }
207
454
  }
208
455
  /**
@@ -222,8 +469,12 @@ var AggregatePipeline = class _AggregatePipeline {
222
469
  * ```
223
470
  */
224
471
  async explain() {
225
- const cursor = this.nativeCollection.aggregate(this.stages);
226
- return await cursor.explain();
472
+ try {
473
+ const cursor = this.nativeCollection.aggregate(this.stages);
474
+ return await cursor.explain();
475
+ } catch (err) {
476
+ wrapMongoError(err, this.definition.name);
477
+ }
227
478
  }
228
479
  // ── Shape-preserving stages ──────────────────────────────────────
229
480
  /**
@@ -720,7 +971,7 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
720
971
  const serialized = serializeIndexKey(spec.key);
721
972
  const existing = existingByKey.get(serialized);
722
973
  if (!existing) {
723
- if (!dryRun) await native.createIndex(spec.key, spec.options);
974
+ if (!dryRun) await safeCreateIndex(native, spec.key, spec.options);
724
975
  acc.created.push(resolveSpecName(spec));
725
976
  return;
726
977
  }
@@ -733,8 +984,8 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
733
984
  }
734
985
  if (dropOrphaned) {
735
986
  if (!dryRun) {
736
- await native.dropIndex(existingName);
737
- await native.createIndex(spec.key, spec.options);
987
+ await safeDropIndex(native, existingName);
988
+ await safeCreateIndex(native, spec.key, spec.options);
738
989
  }
739
990
  acc.dropped.push(existingName);
740
991
  acc.created.push(resolveSpecName(spec));
@@ -747,6 +998,20 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
747
998
  desired: spec.options
748
999
  });
749
1000
  }
1001
+ async function safeCreateIndex(native, key, options) {
1002
+ try {
1003
+ await native.createIndex(key, options);
1004
+ } catch (err) {
1005
+ wrapMongoError(err, native.collectionName);
1006
+ }
1007
+ }
1008
+ async function safeDropIndex(native, name) {
1009
+ try {
1010
+ await native.dropIndex(name);
1011
+ } catch (err) {
1012
+ wrapMongoError(err, native.collectionName);
1013
+ }
1014
+ }
750
1015
  async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys, native, dryRun, dropOrphaned, dropped) {
751
1016
  for (const idx of existingIndexes) {
752
1017
  const rawName = idx["name"];
@@ -755,7 +1020,7 @@ async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys,
755
1020
  const serialized = serializeIndexKey(idx["key"]);
756
1021
  if (matchedKeys.has(serialized) || desiredKeys.has(serialized)) continue;
757
1022
  if (dropOrphaned) {
758
- if (!dryRun) await native.dropIndex(name);
1023
+ if (!dryRun) await safeDropIndex(native, name);
759
1024
  dropped.push(name);
760
1025
  }
761
1026
  }
@@ -767,7 +1032,7 @@ async function listIndexesSafe(native) {
767
1032
  if (err instanceof Error && err.message.includes("ns does not exist")) {
768
1033
  return [];
769
1034
  }
770
- throw err;
1035
+ wrapMongoError(err, native.collectionName);
771
1036
  }
772
1037
  }
773
1038
  async function syncIndexes(handle, options) {
@@ -816,36 +1081,49 @@ async function syncIndexes(handle, options) {
816
1081
  import { z as z2 } from "zod";
817
1082
 
818
1083
  // src/errors/validation.ts
819
- var ZodmonValidationError = class extends Error {
1084
+ var ZodmonValidationError = class extends ZodmonError {
820
1085
  name = "ZodmonValidationError";
821
- /** The MongoDB collection name where the validation failed. */
822
- collection;
823
1086
  /** The original Zod validation error with detailed issue information. */
824
1087
  zodError;
825
- constructor(collection2, zodError) {
1088
+ /** The document that failed validation. */
1089
+ document;
1090
+ constructor(collection2, zodError, document) {
826
1091
  const fields = zodError.issues.map((issue) => {
827
1092
  const path = issue.path.join(".") || "(root)";
828
1093
  return `${path} (${issue.message})`;
829
1094
  }).join(", ");
830
- super(`Validation failed for "${collection2}": ${fields}`);
831
- this.collection = collection2;
1095
+ super(`Validation failed for "${collection2}": ${fields}`, collection2, { cause: zodError });
832
1096
  this.zodError = zodError;
1097
+ this.document = document;
833
1098
  }
834
1099
  };
835
1100
 
836
1101
  // src/crud/delete.ts
837
1102
  async function deleteOne(handle, filter) {
838
- return await handle.native.deleteOne(filter);
1103
+ try {
1104
+ return await handle.native.deleteOne(filter);
1105
+ } catch (err) {
1106
+ wrapMongoError(err, handle.definition.name);
1107
+ }
839
1108
  }
840
1109
  async function deleteMany(handle, filter) {
841
- return await handle.native.deleteMany(filter);
1110
+ try {
1111
+ return await handle.native.deleteMany(filter);
1112
+ } catch (err) {
1113
+ wrapMongoError(err, handle.definition.name);
1114
+ }
842
1115
  }
843
1116
  async function findOneAndDelete(handle, filter, options) {
844
- const result = await handle.native.findOneAndDelete(
845
- // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
846
- filter,
847
- { includeResultMetadata: false }
848
- );
1117
+ let result;
1118
+ try {
1119
+ result = await handle.native.findOneAndDelete(
1120
+ // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1121
+ filter,
1122
+ { includeResultMetadata: false }
1123
+ );
1124
+ } catch (err) {
1125
+ wrapMongoError(err, handle.definition.name);
1126
+ }
849
1127
  if (!result) return null;
850
1128
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
851
1129
  if (mode === false || mode === "passthrough") {
@@ -855,7 +1133,7 @@ async function findOneAndDelete(handle, filter, options) {
855
1133
  return handle.definition.schema.parse(result);
856
1134
  } catch (err) {
857
1135
  if (err instanceof z2.ZodError) {
858
- throw new ZodmonValidationError(handle.definition.name, err);
1136
+ throw new ZodmonValidationError(handle.definition.name, err, result);
859
1137
  }
860
1138
  throw err;
861
1139
  }
@@ -865,13 +1143,13 @@ async function findOneAndDelete(handle, filter, options) {
865
1143
  import { z as z4 } from "zod";
866
1144
 
867
1145
  // src/errors/not-found.ts
868
- var ZodmonNotFoundError = class extends Error {
1146
+ var ZodmonNotFoundError = class extends ZodmonError {
869
1147
  name = "ZodmonNotFoundError";
870
- /** The MongoDB collection name where the query found no results. */
871
- collection;
872
- constructor(collection2) {
873
- super(`Document not found in "${collection2}"`);
874
- this.collection = collection2;
1148
+ /** The filter that produced no results. */
1149
+ filter;
1150
+ constructor(collection2, filter) {
1151
+ super(`Document not found in "${collection2}"`, collection2);
1152
+ this.filter = filter;
875
1153
  }
876
1154
  };
877
1155
 
@@ -1072,10 +1350,17 @@ var TypedFindCursor = class {
1072
1350
  }
1073
1351
  /** @internal Offset pagination implementation. */
1074
1352
  async offsetPaginate(_sortKeys, sort, opts) {
1075
- const [total, raw2] = await Promise.all([
1076
- this.nativeCollection.countDocuments(this.filter),
1077
- this.nativeCollection.find(this.filter).sort(sort).skip((opts.page - 1) * opts.perPage).limit(opts.perPage).toArray()
1078
- ]);
1353
+ let total;
1354
+ let raw2;
1355
+ try {
1356
+ ;
1357
+ [total, raw2] = await Promise.all([
1358
+ this.nativeCollection.countDocuments(this.filter),
1359
+ this.nativeCollection.find(this.filter).sort(sort).skip((opts.page - 1) * opts.perPage).limit(opts.perPage).toArray()
1360
+ ]);
1361
+ } catch (err) {
1362
+ wrapMongoError(err, this.collectionName);
1363
+ }
1079
1364
  const docs = raw2.map((doc) => this.validateDoc(doc));
1080
1365
  const totalPages = Math.ceil(total / opts.perPage);
1081
1366
  return {
@@ -1099,7 +1384,12 @@ var TypedFindCursor = class {
1099
1384
  combinedFilter = this.filter && Object.keys(this.filter).length > 0 ? { $and: [this.filter, cursorFilter] } : cursorFilter;
1100
1385
  }
1101
1386
  const effectiveSort = isBackward ? Object.fromEntries(sortKeys2.map(([f, d]) => [f, d === 1 ? -1 : 1])) : sort;
1102
- const raw2 = await this.nativeCollection.find(combinedFilter).sort(effectiveSort).limit(opts.limit + 1).toArray();
1387
+ let raw2;
1388
+ try {
1389
+ raw2 = await this.nativeCollection.find(combinedFilter).sort(effectiveSort).limit(opts.limit + 1).toArray();
1390
+ } catch (err) {
1391
+ wrapMongoError(err, this.collectionName);
1392
+ }
1103
1393
  const hasMore = raw2.length > opts.limit;
1104
1394
  if (hasMore) raw2.pop();
1105
1395
  if (isBackward) raw2.reverse();
@@ -1127,7 +1417,12 @@ var TypedFindCursor = class {
1127
1417
  * ```
1128
1418
  */
1129
1419
  async toArray() {
1130
- const raw2 = await this.cursor.toArray();
1420
+ let raw2;
1421
+ try {
1422
+ raw2 = await this.cursor.toArray();
1423
+ } catch (err) {
1424
+ wrapMongoError(err, this.collectionName);
1425
+ }
1131
1426
  return raw2.map((doc) => this.validateDoc(doc));
1132
1427
  }
1133
1428
  /**
@@ -1147,8 +1442,12 @@ var TypedFindCursor = class {
1147
1442
  * ```
1148
1443
  */
1149
1444
  async *[Symbol.asyncIterator]() {
1150
- for await (const doc of this.cursor) {
1151
- yield this.validateDoc(doc);
1445
+ try {
1446
+ for await (const doc of this.cursor) {
1447
+ yield this.validateDoc(doc);
1448
+ }
1449
+ } catch (err) {
1450
+ wrapMongoError(err, this.collectionName);
1152
1451
  }
1153
1452
  }
1154
1453
  /** @internal Validate a single raw document against the schema. */
@@ -1160,7 +1459,7 @@ var TypedFindCursor = class {
1160
1459
  return this.schema.parse(raw2);
1161
1460
  } catch (err) {
1162
1461
  if (err instanceof z3.ZodError) {
1163
- throw new ZodmonValidationError(this.collectionName, err);
1462
+ throw new ZodmonValidationError(this.collectionName, err, raw2);
1164
1463
  }
1165
1464
  throw err;
1166
1465
  }
@@ -1171,7 +1470,12 @@ var TypedFindCursor = class {
1171
1470
  async function findOne(handle, filter, options) {
1172
1471
  checkUnindexedFields(handle.definition, filter);
1173
1472
  const findOptions = options?.project ? { projection: options.project } : void 0;
1174
- const raw2 = await handle.native.findOne(filter, findOptions);
1473
+ let raw2;
1474
+ try {
1475
+ raw2 = await handle.native.findOne(filter, findOptions);
1476
+ } catch (err) {
1477
+ wrapMongoError(err, handle.definition.name);
1478
+ }
1175
1479
  if (!raw2) return null;
1176
1480
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
1177
1481
  if (mode === false || mode === "passthrough") {
@@ -1181,7 +1485,7 @@ async function findOne(handle, filter, options) {
1181
1485
  return handle.definition.schema.parse(raw2);
1182
1486
  } catch (err) {
1183
1487
  if (err instanceof z4.ZodError) {
1184
- throw new ZodmonValidationError(handle.definition.name, err);
1488
+ throw new ZodmonValidationError(handle.definition.name, err, raw2);
1185
1489
  }
1186
1490
  throw err;
1187
1491
  }
@@ -1189,7 +1493,7 @@ async function findOne(handle, filter, options) {
1189
1493
  async function findOneOrThrow(handle, filter, options) {
1190
1494
  const doc = await findOne(handle, filter, options);
1191
1495
  if (!doc) {
1192
- throw new ZodmonNotFoundError(handle.definition.name);
1496
+ throw new ZodmonNotFoundError(handle.definition.name, filter);
1193
1497
  }
1194
1498
  return doc;
1195
1499
  }
@@ -1209,11 +1513,15 @@ async function insertOne(handle, doc) {
1209
1513
  parsed = handle.definition.schema.parse(doc);
1210
1514
  } catch (err) {
1211
1515
  if (err instanceof z5.ZodError) {
1212
- throw new ZodmonValidationError(handle.definition.name, err);
1516
+ throw new ZodmonValidationError(handle.definition.name, err, doc);
1213
1517
  }
1214
1518
  throw err;
1215
1519
  }
1216
- await handle.native.insertOne(parsed);
1520
+ try {
1521
+ await handle.native.insertOne(parsed);
1522
+ } catch (err) {
1523
+ wrapMongoError(err, handle.definition.name);
1524
+ }
1217
1525
  return parsed;
1218
1526
  }
1219
1527
  async function insertMany(handle, docs) {
@@ -1224,22 +1532,34 @@ async function insertMany(handle, docs) {
1224
1532
  parsed.push(handle.definition.schema.parse(doc));
1225
1533
  } catch (err) {
1226
1534
  if (err instanceof z5.ZodError) {
1227
- throw new ZodmonValidationError(handle.definition.name, err);
1535
+ throw new ZodmonValidationError(handle.definition.name, err, doc);
1228
1536
  }
1229
1537
  throw err;
1230
1538
  }
1231
1539
  }
1232
- await handle.native.insertMany(parsed);
1540
+ try {
1541
+ await handle.native.insertMany(parsed);
1542
+ } catch (err) {
1543
+ wrapMongoError(err, handle.definition.name);
1544
+ }
1233
1545
  return parsed;
1234
1546
  }
1235
1547
 
1236
1548
  // src/crud/update.ts
1237
1549
  import { z as z6 } from "zod";
1238
1550
  async function updateOne(handle, filter, update, options) {
1239
- return await handle.native.updateOne(filter, update, options);
1551
+ try {
1552
+ return await handle.native.updateOne(filter, update, options);
1553
+ } catch (err) {
1554
+ wrapMongoError(err, handle.definition.name);
1555
+ }
1240
1556
  }
1241
1557
  async function updateMany(handle, filter, update, options) {
1242
- return await handle.native.updateMany(filter, update, options);
1558
+ try {
1559
+ return await handle.native.updateMany(filter, update, options);
1560
+ } catch (err) {
1561
+ wrapMongoError(err, handle.definition.name);
1562
+ }
1243
1563
  }
1244
1564
  async function findOneAndUpdate(handle, filter, update, options) {
1245
1565
  const driverOptions = {
@@ -1249,14 +1569,19 @@ async function findOneAndUpdate(handle, filter, update, options) {
1249
1569
  if (options?.upsert !== void 0) {
1250
1570
  driverOptions["upsert"] = options.upsert;
1251
1571
  }
1252
- const result = await handle.native.findOneAndUpdate(
1253
- // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1254
- filter,
1255
- // biome-ignore lint/suspicious/noExplicitAny: TypedUpdateFilter intersection type is not directly assignable to MongoDB's UpdateFilter
1256
- update,
1257
- // biome-ignore lint/suspicious/noExplicitAny: dynamic options object is not assignable to driver's FindOneAndUpdateOptions under exactOptionalPropertyTypes
1258
- driverOptions
1259
- );
1572
+ let result;
1573
+ try {
1574
+ result = await handle.native.findOneAndUpdate(
1575
+ // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1576
+ filter,
1577
+ // biome-ignore lint/suspicious/noExplicitAny: TypedUpdateFilter intersection type is not directly assignable to MongoDB's UpdateFilter
1578
+ update,
1579
+ // biome-ignore lint/suspicious/noExplicitAny: dynamic options object is not assignable to driver's FindOneAndUpdateOptions under exactOptionalPropertyTypes
1580
+ driverOptions
1581
+ );
1582
+ } catch (err) {
1583
+ wrapMongoError(err, handle.definition.name);
1584
+ }
1260
1585
  if (!result) return null;
1261
1586
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
1262
1587
  if (mode === false || mode === "passthrough") {
@@ -1266,7 +1591,7 @@ async function findOneAndUpdate(handle, filter, update, options) {
1266
1591
  return handle.definition.schema.parse(result);
1267
1592
  } catch (err) {
1268
1593
  if (err instanceof z6.ZodError) {
1269
- throw new ZodmonValidationError(handle.definition.name, err);
1594
+ throw new ZodmonValidationError(handle.definition.name, err, result);
1270
1595
  }
1271
1596
  throw err;
1272
1597
  }
@@ -1957,8 +2282,18 @@ export {
1957
2282
  Database,
1958
2283
  IndexBuilder,
1959
2284
  TypedFindCursor,
2285
+ ZodmonAuthError,
2286
+ ZodmonBulkWriteError,
2287
+ ZodmonDocValidationError,
2288
+ ZodmonDuplicateKeyError,
2289
+ ZodmonError,
2290
+ ZodmonIndexError,
2291
+ ZodmonNetworkError,
1960
2292
  ZodmonNotFoundError,
2293
+ ZodmonQueryError,
2294
+ ZodmonTimeoutError,
1961
2295
  ZodmonValidationError,
2296
+ ZodmonWriteConflictError,
1962
2297
  aggregate,
1963
2298
  checkUnindexedFields,
1964
2299
  collection,
@@ -1990,6 +2325,7 @@ export {
1990
2325
  toCompoundIndexSpec,
1991
2326
  toFieldIndexSpec,
1992
2327
  updateMany,
1993
- updateOne
2328
+ updateOne,
2329
+ wrapMongoError
1994
2330
  };
1995
2331
  //# sourceMappingURL=index.js.map