effect-mongodb 0.1.2 → 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 +22 -16
  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 +2 -2
  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 +22 -16
  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 +30 -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
@@ -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.2"
1
+ let moduleVersion = "0.1.3"
2
2
 
3
3
  export const getCurrentVersion = () => moduleVersion
4
4