effect-mongodb 0.1.1 → 0.1.3

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.
Files changed (74) hide show
  1. package/dist/cjs/AggregationCursor.js +9 -5
  2. package/dist/cjs/AggregationCursor.js.map +1 -1
  3. package/dist/cjs/Collection.js +23 -17
  4. package/dist/cjs/Collection.js.map +1 -1
  5. package/dist/cjs/Db.js +7 -1
  6. package/dist/cjs/Db.js.map +1 -1
  7. package/dist/cjs/DocumentAggregationCursor.js +9 -5
  8. package/dist/cjs/DocumentAggregationCursor.js.map +1 -1
  9. package/dist/cjs/DocumentCollection.js +24 -15
  10. package/dist/cjs/DocumentCollection.js.map +1 -1
  11. package/dist/cjs/DocumentFindCursor.js +9 -5
  12. package/dist/cjs/DocumentFindCursor.js.map +1 -1
  13. package/dist/cjs/FindCursor.js +11 -10
  14. package/dist/cjs/FindCursor.js.map +1 -1
  15. package/dist/cjs/ListCollectionsCursor.js +9 -5
  16. package/dist/cjs/ListCollectionsCursor.js.map +1 -1
  17. package/dist/cjs/MongoClient.js +8 -2
  18. package/dist/cjs/MongoClient.js.map +1 -1
  19. package/dist/cjs/MongoError.js +7 -18
  20. package/dist/cjs/MongoError.js.map +1 -1
  21. package/dist/cjs/internal/mongo-error.js +27 -0
  22. package/dist/cjs/internal/mongo-error.js.map +1 -0
  23. package/dist/cjs/internal/version.js +1 -1
  24. package/dist/dts/AggregationCursor.d.ts.map +1 -1
  25. package/dist/dts/Collection.d.ts +12 -12
  26. package/dist/dts/Collection.d.ts.map +1 -1
  27. package/dist/dts/Db.d.ts.map +1 -1
  28. package/dist/dts/DocumentAggregationCursor.d.ts.map +1 -1
  29. package/dist/dts/DocumentCollection.d.ts +6 -5
  30. package/dist/dts/DocumentCollection.d.ts.map +1 -1
  31. package/dist/dts/DocumentFindCursor.d.ts.map +1 -1
  32. package/dist/dts/FindCursor.d.ts.map +1 -1
  33. package/dist/dts/ListCollectionsCursor.d.ts.map +1 -1
  34. package/dist/dts/MongoClient.d.ts.map +1 -1
  35. package/dist/dts/MongoError.d.ts +32 -12
  36. package/dist/dts/MongoError.d.ts.map +1 -1
  37. package/dist/dts/internal/mongo-error.d.ts +5 -0
  38. package/dist/dts/internal/mongo-error.d.ts.map +1 -0
  39. package/dist/esm/AggregationCursor.js +9 -5
  40. package/dist/esm/AggregationCursor.js.map +1 -1
  41. package/dist/esm/Collection.js +23 -17
  42. package/dist/esm/Collection.js.map +1 -1
  43. package/dist/esm/Db.js +7 -1
  44. package/dist/esm/Db.js.map +1 -1
  45. package/dist/esm/DocumentAggregationCursor.js +9 -5
  46. package/dist/esm/DocumentAggregationCursor.js.map +1 -1
  47. package/dist/esm/DocumentCollection.js +24 -15
  48. package/dist/esm/DocumentCollection.js.map +1 -1
  49. package/dist/esm/DocumentFindCursor.js +9 -5
  50. package/dist/esm/DocumentFindCursor.js.map +1 -1
  51. package/dist/esm/FindCursor.js +11 -10
  52. package/dist/esm/FindCursor.js.map +1 -1
  53. package/dist/esm/ListCollectionsCursor.js +9 -5
  54. package/dist/esm/ListCollectionsCursor.js.map +1 -1
  55. package/dist/esm/MongoClient.js +8 -2
  56. package/dist/esm/MongoClient.js.map +1 -1
  57. package/dist/esm/MongoError.js +3 -17
  58. package/dist/esm/MongoError.js.map +1 -1
  59. package/dist/esm/internal/mongo-error.js +18 -0
  60. package/dist/esm/internal/mongo-error.js.map +1 -0
  61. package/dist/esm/internal/version.js +1 -1
  62. package/package.json +1 -1
  63. package/src/AggregationCursor.ts +12 -3
  64. package/src/Collection.ts +47 -38
  65. package/src/Db.ts +5 -1
  66. package/src/DocumentAggregationCursor.ts +12 -3
  67. package/src/DocumentCollection.ts +37 -20
  68. package/src/DocumentFindCursor.ts +12 -3
  69. package/src/FindCursor.ts +15 -6
  70. package/src/ListCollectionsCursor.ts +12 -3
  71. package/src/MongoClient.ts +6 -2
  72. package/src/MongoError.ts +24 -32
  73. package/src/internal/mongo-error.ts +34 -0
  74. package/src/internal/version.ts +1 -1
@@ -40,6 +40,7 @@ import * as Collection from "./Collection.js"
40
40
  import * as DocumentAggregationCursor from "./DocumentAggregationCursor.js"
41
41
  import * as DocumentFindCursor from "./DocumentFindCursor.js"
42
42
  import type { ModifyResult } from "./internal/modify-result.js"
43
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
43
44
  import * as MongoError from "./MongoError.js"
44
45
 
45
46
  export class DocumentCollection extends Data.TaggedClass("DocumentCollection")<{
@@ -86,11 +87,15 @@ export const findOne: {
86
87
  F.pipe(
87
88
  Effect.promise(() => collection.collection.findOne(filter, options)),
88
89
  Effect.map((value) => O.fromNullable(value)),
89
- Effect.catchAllDefect(MongoError.mongoErrorDie<O.Option<Document>>("findOne error"))
90
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "findOne")))
90
91
  )
91
92
  )
92
93
 
93
94
  export const insertOne: {
95
+ (
96
+ collection: DocumentCollection,
97
+ doc: OptionalUnlessRequiredId<Document>
98
+ ): Effect.Effect<InsertOneResult, MongoError.MongoError>
94
99
  (doc: OptionalUnlessRequiredId<Document>, options?: InsertOneOptions): (
95
100
  collection: DocumentCollection
96
101
  ) => Effect.Effect<InsertOneResult, MongoError.MongoError>
@@ -106,7 +111,7 @@ export const insertOne: {
106
111
  ): Effect.Effect<InsertOneResult, MongoError.MongoError> =>
107
112
  F.pipe(
108
113
  Effect.promise(() => collection.collection.insertOne(doc, options)),
109
- Effect.catchAllDefect(MongoError.mongoErrorDie<InsertOneResult>("insertOne error"))
114
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertOne")))
110
115
  ))
111
116
 
112
117
  export const insertMany: {
@@ -115,12 +120,12 @@ export const insertMany: {
115
120
  options?: BulkWriteOptions
116
121
  ): (
117
122
  collection: DocumentCollection
118
- ) => Effect.Effect<InsertOneResult, MongoError.MongoError>
123
+ ) => Effect.Effect<InsertManyResult, MongoError.MongoError>
119
124
  (
120
125
  collection: DocumentCollection,
121
126
  docs: ReadonlyArray<OptionalUnlessRequiredId<Document>>,
122
127
  options?: BulkWriteOptions
123
- ): Effect.Effect<InsertOneResult, MongoError.MongoError>
128
+ ): Effect.Effect<InsertManyResult, MongoError.MongoError>
124
129
  } = F.dual((args) => isDocumentCollection(args[0]), (
125
130
  collection: DocumentCollection,
126
131
  docs: ReadonlyArray<OptionalUnlessRequiredId<Document>>,
@@ -128,7 +133,7 @@ export const insertMany: {
128
133
  ): Effect.Effect<InsertManyResult, MongoError.MongoError> =>
129
134
  F.pipe(
130
135
  Effect.promise(() => collection.collection.insertMany(docs, options)),
131
- Effect.catchAllDefect(MongoError.mongoErrorDie<InsertManyResult>("insertMany error"))
136
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertMany")))
132
137
  ))
133
138
 
134
139
  export const deleteOne: {
@@ -149,7 +154,7 @@ export const deleteOne: {
149
154
  ): Effect.Effect<DeleteResult, MongoError.MongoError> =>
150
155
  F.pipe(
151
156
  Effect.promise(() => collection.collection.deleteOne(filter, options)),
152
- Effect.catchAllDefect(MongoError.mongoErrorDie<DeleteResult>("deleteOne error"))
157
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteOne")))
153
158
  )
154
159
  )
155
160
 
@@ -171,7 +176,7 @@ export const deleteMany: {
171
176
  ): Effect.Effect<DeleteResult, MongoError.MongoError> =>
172
177
  F.pipe(
173
178
  Effect.promise(() => collection.collection.deleteMany(filter, options)),
174
- Effect.catchAllDefect(MongoError.mongoErrorDie<DeleteResult>("deleteMany error"))
179
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteMany")))
175
180
  )
176
181
  )
177
182
 
@@ -201,7 +206,7 @@ export const updateMany: {
201
206
  Effect.promise(() =>
202
207
  collection.collection.updateMany(filter, Array.isArray(update) ? [...update] : update, options)
203
208
  ),
204
- Effect.catchAllDefect(MongoError.mongoErrorDie<UpdateResult>("updateMany error"))
209
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "updateMany")))
205
210
  )
206
211
  )
207
212
 
@@ -229,7 +234,7 @@ export const replaceOne: {
229
234
  ): Effect.Effect<UpdateResult | Document, MongoError.MongoError> =>
230
235
  F.pipe(
231
236
  Effect.promise(() => collection.collection.replaceOne(filter, replacement, options)),
232
- Effect.catchAllDefect(MongoError.mongoErrorDie<UpdateResult | Document>("replaceOne error"))
237
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "replaceOne")))
233
238
  )
234
239
  )
235
240
 
@@ -299,7 +304,7 @@ export const findOneAndReplace: {
299
304
  return O.fromNullable(value)
300
305
  }),
301
306
  Effect.catchAllDefect(
302
- MongoError.mongoErrorDie<O.Option<Document> | ModifyResult<Document>>("findOneAndReplace error")
307
+ mongoErrorOrDie(errorSource(collection, "findOneAndReplace"))
303
308
  )
304
309
  )
305
310
  )
@@ -307,22 +312,23 @@ export const findOneAndReplace: {
307
312
  export const rename: {
308
313
  (newName: string, options?: RenameOptions): (
309
314
  collection: DocumentCollection
310
- ) => Effect.Effect<MongoCollection, MongoError.MongoError>
315
+ ) => Effect.Effect<DocumentCollection, MongoError.MongoError>
311
316
  (
312
317
  collection: DocumentCollection,
313
318
  newName: string,
314
319
  options?: RenameOptions
315
- ): Effect.Effect<MongoCollection, MongoError.MongoError>
320
+ ): Effect.Effect<DocumentCollection, MongoError.MongoError>
316
321
  } = F.dual(
317
322
  (args) => isDocumentCollection(args[0]),
318
323
  (
319
324
  collection: DocumentCollection,
320
325
  newName: string,
321
326
  options?: RenameOptions
322
- ): Effect.Effect<MongoCollection, MongoError.MongoError> =>
327
+ ): Effect.Effect<DocumentCollection, MongoError.MongoError> =>
323
328
  F.pipe(
324
329
  Effect.promise(() => collection.collection.rename(newName, options)),
325
- Effect.catchAllDefect(MongoError.mongoErrorDie<MongoCollection>("rename error"))
330
+ Effect.map((collection) => new DocumentCollection({ collection })),
331
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "rename")))
326
332
  )
327
333
  )
328
334
 
@@ -337,7 +343,7 @@ export const drop: {
337
343
  ): Effect.Effect<boolean, MongoError.MongoError> =>
338
344
  F.pipe(
339
345
  Effect.promise(() => collection.collection.drop(options)),
340
- Effect.catchAllDefect(MongoError.mongoErrorDie<boolean>("drop error"))
346
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "drop")))
341
347
  )
342
348
  )
343
349
 
@@ -359,7 +365,7 @@ export const createIndexes: {
359
365
  ): Effect.Effect<Array<string>, MongoError.MongoError> =>
360
366
  F.pipe(
361
367
  Effect.promise(() => collection.collection.createIndexes([...indexSpecs], options)),
362
- Effect.catchAllDefect(MongoError.mongoErrorDie<Array<string>>("createIndexes error"))
368
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndexes")))
363
369
  )
364
370
  )
365
371
 
@@ -382,7 +388,7 @@ export const createIndex: {
382
388
  ): Effect.Effect<string, MongoError.MongoError> =>
383
389
  F.pipe(
384
390
  Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
385
- Effect.catchAllDefect(MongoError.mongoErrorDie<string>("createIndex error"))
391
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndex")))
386
392
  )
387
393
  )
388
394
 
@@ -405,7 +411,7 @@ export const dropIndex: {
405
411
  ): Effect.Effect<Document, MongoError.MongoError> =>
406
412
  F.pipe(
407
413
  Effect.promise(() => collection.collection.dropIndex(indexName, options)),
408
- Effect.catchAllDefect(MongoError.mongoErrorDie<Document>("dropIndex error"))
414
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "dropIndex")))
409
415
  )
410
416
  )
411
417
 
@@ -446,7 +452,7 @@ export const estimatedDocumentCount: {
446
452
  ): Effect.Effect<number, MongoError.MongoError> =>
447
453
  F.pipe(
448
454
  Effect.promise(() => collection.collection.estimatedDocumentCount(options)),
449
- Effect.catchAllDefect(MongoError.mongoErrorDie<number>("estimatedDocumentCount error"))
455
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "estimatedDocumentCount")))
450
456
  )
451
457
  )
452
458
 
@@ -468,7 +474,7 @@ export const countDocuments: {
468
474
  ): Effect.Effect<number, MongoError.MongoError> =>
469
475
  F.pipe(
470
476
  Effect.promise(() => collection.collection.countDocuments(filter, options)),
471
- Effect.catchAllDefect(MongoError.mongoErrorDie<number>("countDocuments error"))
477
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "countDocuments")))
472
478
  )
473
479
  )
474
480
 
@@ -486,3 +492,14 @@ export const typed: {
486
492
  ): Collection.Collection<A, I, R> => new Collection.Collection<A, I, R>({ collection: collection.collection, schema }))
487
493
 
488
494
  const isDocumentCollection = (x: unknown) => x instanceof DocumentCollection
495
+
496
+ const errorSource = (
497
+ collection: DocumentCollection,
498
+ functionName: string
499
+ ) =>
500
+ new MongoError.CollectionErrorSource({
501
+ module: DocumentCollection.name,
502
+ functionName,
503
+ db: collection.collection.dbName,
504
+ collection: collection.collection.collectionName
505
+ })
@@ -8,6 +8,7 @@ import type * as Schema from "effect/Schema"
8
8
  import * as Stream from "effect/Stream"
9
9
  import type { Document, Filter, FindCursor as MongoFindCursor, Sort, SortDirection } from "mongodb"
10
10
  import * as FindCursor from "./FindCursor.js"
11
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
11
12
  import * as MongoError from "./MongoError.js"
12
13
 
13
14
  export class DocumentFindCursor extends Data.TaggedClass("DocumentFindCursor")<{
@@ -53,8 +54,8 @@ export const limit: {
53
54
 
54
55
  export const toArray = (cursor: DocumentFindCursor): Effect.Effect<Array<Document>, MongoError.MongoError> =>
55
56
  F.pipe(
56
- Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }),
57
- Effect.catchAll(MongoError.mongoErrorDie<Array<Document>>("toArray error"))
57
+ Effect.promise(() => cursor.cursor.toArray()),
58
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
58
59
  )
59
60
 
60
61
  export const toStream = (
@@ -62,7 +63,7 @@ export const toStream = (
62
63
  ): Stream.Stream<Document, MongoError.MongoError> =>
63
64
  F.pipe(
64
65
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
65
- Stream.catchAll(MongoError.mongoErrorStream<Document>("Unable to read from mongodb cursor"))
66
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
66
67
  )
67
68
 
68
69
  export const typed: {
@@ -74,3 +75,11 @@ export const typed: {
74
75
  ): FindCursor.FindCursor<A, I, R> => new FindCursor.FindCursor<A, I, R>({ cursor: cursor.cursor, schema }))
75
76
 
76
77
  const isDocumentFindCursor = (x: unknown) => x instanceof DocumentFindCursor
78
+
79
+ const errorSource = (cursor: DocumentFindCursor, functionName: string) =>
80
+ new MongoError.CollectionErrorSource({
81
+ module: DocumentFindCursor.name,
82
+ functionName,
83
+ db: cursor.cursor.namespace.db,
84
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
85
+ })
package/src/FindCursor.ts CHANGED
@@ -11,6 +11,7 @@ import * as Stream from "effect/Stream"
11
11
  import * as Tuple from "effect/Tuple"
12
12
  import type { Document, FindCursor as FindCursor_, Sort, SortDirection } from "mongodb"
13
13
  import type { Filter } from "./internal/filter.js"
14
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
14
15
  import * as MongoError from "./MongoError.js"
15
16
 
16
17
  export class FindCursor<A, I = A, R = never> extends Data.TaggedClass("FindCursor")<{
@@ -78,8 +79,8 @@ export const toArray = <A, I, R>(
78
79
  cursor: FindCursor<A, I, R>
79
80
  ): Effect.Effect<Array<A>, MongoError.MongoError | ParseResult.ParseError, R> => {
80
81
  const decode = Schema.decodeUnknown(cursor.schema)
81
- return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
82
- Effect.catchAll(MongoError.mongoErrorDie<Array<A>>("Unable to get array from mongodb cursor")),
82
+ return Effect.promise(() => cursor.cursor.toArray()).pipe(
83
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray"))),
83
84
  Effect.flatMap(Effect.forEach((x) => decode(x)))
84
85
  )
85
86
  }
@@ -92,8 +93,8 @@ export const toArrayEither = <A, I, R>(
92
93
  R
93
94
  > => {
94
95
  const decode = Schema.decodeUnknown(cursor.schema)
95
- return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
96
- Effect.catchAll(MongoError.mongoErrorDie<Array<unknown>>("Unable to get array from mongodb cursor")),
96
+ return Effect.promise(() => cursor.cursor.toArray()).pipe(
97
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArrayEither"))),
97
98
  Effect.flatMap(Effect.forEach((x) =>
98
99
  F.pipe(
99
100
  decode(x),
@@ -110,7 +111,7 @@ export const toStream = <A, I, R>(
110
111
  const decode = Schema.decodeUnknown(cursor.schema)
111
112
  return F.pipe(
112
113
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
113
- Stream.catchAll(MongoError.mongoErrorStream<A>("Unable to get stream from mongodb cursor")),
114
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream"))),
114
115
  Stream.mapEffect((x) => decode(x))
115
116
  )
116
117
  }
@@ -121,7 +122,7 @@ export const toStreamEither = <A, I, R>(
121
122
  const decode = Schema.decodeUnknown(cursor.schema)
122
123
  return F.pipe(
123
124
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
124
- Stream.catchAll(MongoError.mongoErrorStream<A>("Unable to get stream either from mongodb cursor")),
125
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStreamEither"))),
125
126
  Stream.mapEffect((x) =>
126
127
  F.pipe(
127
128
  // keep new line
@@ -134,3 +135,11 @@ export const toStreamEither = <A, I, R>(
134
135
  }
135
136
 
136
137
  const isFindCursor = (x: unknown): x is FindCursor<unknown> => x instanceof FindCursor
138
+
139
+ const errorSource = <A, I, R>(cursor: FindCursor<A, I, R>, functionName: string) =>
140
+ new MongoError.CollectionErrorSource({
141
+ module: FindCursor.name,
142
+ functionName,
143
+ db: cursor.cursor.namespace.db,
144
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
145
+ })
@@ -9,6 +9,7 @@ import type {
9
9
  CollectionInfo as MongoCollectionInfo,
10
10
  ListCollectionsCursor as MongoListCollectionsCursor
11
11
  } from "mongodb"
12
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
12
13
  import * as MongoError from "./MongoError.js"
13
14
 
14
15
  export type NameOnlyCollectionInfo = Pick<MongoCollectionInfo, "name" | "type">
@@ -32,8 +33,8 @@ export const toArray = <T extends DefaultCollectionInfo>(
32
33
  cursor: ListCollectionsCursor<T>
33
34
  ): Effect.Effect<Array<T>, MongoError.MongoError> =>
34
35
  F.pipe(
35
- Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }),
36
- Effect.catchAll(MongoError.mongoErrorDie<Array<T>>(`${cursor._tag}.toArray error`))
36
+ Effect.promise(() => cursor.cursor.toArray()),
37
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
37
38
  )
38
39
 
39
40
  export const toStream = <T extends DefaultCollectionInfo>(
@@ -41,5 +42,13 @@ export const toStream = <T extends DefaultCollectionInfo>(
41
42
  ): Stream.Stream<T, MongoError.MongoError> =>
42
43
  F.pipe(
43
44
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
44
- Stream.catchAll(MongoError.mongoErrorStream<T>(`${cursor._tag}.toStream error`))
45
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
45
46
  )
47
+
48
+ const errorSource = (cursor: ListCollectionsCursor, functionName: string) =>
49
+ new MongoError.CollectionErrorSource({
50
+ module: ListCollectionsCursor.name,
51
+ functionName,
52
+ db: cursor.cursor.namespace.db,
53
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
54
+ })
@@ -6,6 +6,7 @@ import * as F from "effect/Function"
6
6
  import type * as Scope from "effect/Scope"
7
7
  import type { Db, DbOptions, MongoClientOptions } from "mongodb"
8
8
  import { MongoClient as MongoClient_ } from "mongodb"
9
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
9
10
  import * as MongoError from "./MongoError.js"
10
11
 
11
12
  export type MongoClient = MongoClient_
@@ -15,7 +16,7 @@ export const connect = (
15
16
  options?: MongoClientOptions
16
17
  ): Effect.Effect<MongoClient, MongoError.MongoError> =>
17
18
  Effect.promise(() => MongoClient_.connect(url, options)).pipe(
18
- Effect.catchAll(MongoError.mongoErrorDie<MongoClient_>("connect error"))
19
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource([new URL(url).host], "connect")))
19
20
  )
20
21
 
21
22
  export const close: {
@@ -25,7 +26,7 @@ export const close: {
25
26
  (args) => isMongoClient(args[0]),
26
27
  (client: MongoClient, force?: boolean): Effect.Effect<void, MongoError.MongoError> =>
27
28
  Effect.promise(() => client.close(force)).pipe(
28
- Effect.catchAll(MongoError.mongoErrorDie<void>("close error"))
29
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(client.options.hosts.map((x) => x.host ?? "NO_HOST"), "close")))
29
30
  )
30
31
  )
31
32
 
@@ -47,3 +48,6 @@ export const db: {
47
48
  )
48
49
 
49
50
  const isMongoClient = (x: unknown) => x instanceof MongoClient_
51
+
52
+ const errorSource = (hosts: Array<string>, functionName: string) =>
53
+ new MongoError.ClientErrorSource({ module: "MongoClient", functionName, hosts })
package/src/MongoError.ts CHANGED
@@ -2,39 +2,31 @@
2
2
  * @since 0.0.1
3
3
  */
4
4
  import * as Data from "effect/Data"
5
- import * as Effect from "effect/Effect"
6
- import * as F from "effect/Function"
7
- import * as Match from "effect/Match"
8
- import * as Stream from "effect/Stream"
9
- import { MongoError as MongoError_ } from "mongodb"
5
+ import type { MongoError as MongoError_ } from "mongodb"
10
6
 
11
- export class MongoError extends Data.TaggedError("MongoError")<{
12
- message: string
13
- innerError: MongoError_
7
+ export class ClientErrorSource extends Data.TaggedClass("ClientErrorSource")<{
8
+ module: string
9
+ functionName: string
10
+ hosts: Array<string>
14
11
  }> {}
15
12
 
16
- export const mongoErrorDie: {
17
- <A>(message: string): (error: unknown) => Effect.Effect<A, MongoError>
18
- <A>(error: unknown, message: string): Effect.Effect<A, MongoError>
19
- } = F.dual(2, <A>(error: unknown, message: string): Effect.Effect<A, MongoError> =>
20
- F.pipe(
21
- Match.value(error),
22
- Match.when(Match.instanceOf(MongoError_), (innerError) => Effect.fail(new MongoError({ message, innerError }))),
23
- Match.orElse((cause) =>
24
- Effect.die(
25
- new Error(message, {
26
- cause
27
- })
28
- )
29
- )
30
- ))
13
+ export class DbErrorSource extends Data.TaggedClass("DbErrorSource")<{
14
+ module: string
15
+ functionName: string
16
+ db: string
17
+ }> {}
18
+
19
+ export class CollectionErrorSource extends Data.TaggedClass("CollectionErrorSource")<{
20
+ module: string
21
+ functionName: string
22
+ db: string
23
+ collection: string
24
+ }> {}
31
25
 
32
- export const mongoErrorStream: {
33
- <A>(message: string): (error: unknown) => Stream.Stream<A, MongoError>
34
- <A>(error: unknown, message: string): Stream.Stream<A, MongoError>
35
- } = F.dual(2, <A>(error: unknown, message: string): Stream.Stream<A, MongoError> =>
36
- F.pipe(
37
- Match.value(error),
38
- Match.when(Match.instanceOf(MongoError_), (innerError) => Stream.fail(new MongoError({ message, innerError }))),
39
- Match.orElse((cause) => Stream.die(new Error(message, { cause })))
40
- ))
26
+ export type ErrorSource = ClientErrorSource | DbErrorSource | CollectionErrorSource
27
+
28
+ export class MongoError extends Data.TaggedError("MongoError")<{
29
+ message: string
30
+ cause: MongoError_
31
+ source?: ErrorSource
32
+ }> {}
@@ -0,0 +1,34 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as F from "effect/Function"
3
+ import * as Match from "effect/Match"
4
+ import { MongoError as MongoError_ } from "mongodb"
5
+ import type { ErrorSource } from "../MongoError.js"
6
+ import { MongoError } from "../MongoError.js"
7
+
8
+ export const mongoErrorOrDie =
9
+ (source: ErrorSource, message?: string) => (error: unknown): Effect.Effect<never, MongoError> =>
10
+ F.pipe(
11
+ Match.value(error),
12
+ Match.when(Match.instanceOf(MongoError_), F.flow(makeMongoError(source, message), Effect.fail)),
13
+ Match.orElse(F.flow(makeError(source, message), Effect.die))
14
+ )
15
+
16
+ const makeMongoError = (source: ErrorSource, message: string | undefined) => (cause: MongoError_) =>
17
+ new MongoError({ message: messageFrom(source, message), cause, source })
18
+
19
+ const makeError = (source: ErrorSource, message: string | undefined) => (cause: unknown) =>
20
+ new Error(messageFrom(source, message), { cause })
21
+
22
+ const messageFrom = (source: ErrorSource, message?: string) =>
23
+ message ? `${messageFromSource(source)} - ${message}` : messageFromSource(source)
24
+
25
+ const messageFromSource = (source: ErrorSource) =>
26
+ F.pipe(
27
+ Match.value(source),
28
+ Match.tag("ClientErrorSource", (s) => `${baseMessage(s)} - hosts ${s.hosts.join(", ")}`),
29
+ Match.tag("DbErrorSource", (s) => `${baseMessage(s)} - ${s.db}`),
30
+ Match.tag("CollectionErrorSource", (s) => `${baseMessage(s)} - ${s.db}.${s.collection}`),
31
+ Match.exhaustive
32
+ )
33
+
34
+ const baseMessage = (s: { module: string; functionName: string }) => `Error in ${s.module}.${s.functionName}`
@@ -1,4 +1,4 @@
1
- let moduleVersion = "0.1.1"
1
+ let moduleVersion = "0.1.3"
2
2
 
3
3
  export const getCurrentVersion = () => moduleVersion
4
4