@mastra/mongodb 0.11.0 → 0.11.1-alpha.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mongodb",
3
- "version": "0.11.0",
3
+ "version": "0.11.1-alpha.1",
4
4
  "description": "MongoDB provider for Mastra - includes vector store capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,9 +31,9 @@
31
31
  "tsup": "^8.5.0",
32
32
  "typescript": "^5.8.3",
33
33
  "vitest": "^3.2.3",
34
- "@internal/lint": "0.0.13",
35
34
  "@internal/storage-test-utils": "0.0.9",
36
- "@mastra/core": "0.10.6"
35
+ "@mastra/core": "0.10.7-alpha.1",
36
+ "@internal/lint": "0.0.13"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@mastra/core": ">=0.10.4-0 <0.11.0"
@@ -1,4 +1,6 @@
1
1
  import { MessageList } from '@mastra/core/agent';
2
+ import type { MastraMessageContentV2 } from '@mastra/core/agent';
3
+ import { ErrorDomain, ErrorCategory, MastraError } from '@mastra/core/error';
2
4
  import type { MetricResult, TestInfo } from '@mastra/core/eval';
3
5
  import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
4
6
  import type {
@@ -47,15 +49,27 @@ export class MongoDBStore extends MastraStorage {
47
49
  super({ name: 'MongoDBStore' });
48
50
  this.#isConnected = false;
49
51
 
50
- if (!config.url?.trim().length) {
51
- throw new Error(
52
- 'MongoDBStore: url must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults.',
53
- );
54
- }
52
+ try {
53
+ if (!config.url?.trim().length) {
54
+ throw new Error(
55
+ 'MongoDBStore: url must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults.',
56
+ );
57
+ }
55
58
 
56
- if (!config.dbName?.trim().length) {
57
- throw new Error(
58
- 'MongoDBStore: dbName must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults.',
59
+ if (!config.dbName?.trim().length) {
60
+ throw new Error(
61
+ 'MongoDBStore: dbName must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults.',
62
+ );
63
+ }
64
+ } catch (error) {
65
+ throw new MastraError(
66
+ {
67
+ id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
68
+ domain: ErrorDomain.STORAGE,
69
+ category: ErrorCategory.USER,
70
+ details: { url: config.url, dbName: config.dbName },
71
+ },
72
+ error,
59
73
  );
60
74
  }
61
75
 
@@ -103,7 +117,17 @@ export class MongoDBStore extends MastraStorage {
103
117
  await collection.deleteMany({});
104
118
  } catch (error) {
105
119
  if (error instanceof Error) {
106
- this.logger.error(error.message);
120
+ const matstraError = new MastraError(
121
+ {
122
+ id: 'STORAGE_MONGODB_STORE_CLEAR_TABLE_FAILED',
123
+ domain: ErrorDomain.STORAGE,
124
+ category: ErrorCategory.THIRD_PARTY,
125
+ details: { tableName },
126
+ },
127
+ error,
128
+ );
129
+ this.logger.error(matstraError.message);
130
+ this.logger?.trackException(matstraError);
107
131
  }
108
132
  }
109
133
  }
@@ -113,8 +137,19 @@ export class MongoDBStore extends MastraStorage {
113
137
  const collection = await this.getCollection(tableName);
114
138
  await collection.insertOne(record);
115
139
  } catch (error) {
116
- this.logger.error(`Error upserting into table ${tableName}: ${error}`);
117
- throw error;
140
+ if (error instanceof Error) {
141
+ const matstraError = new MastraError(
142
+ {
143
+ id: 'STORAGE_MONGODB_STORE_INSERT_FAILED',
144
+ domain: ErrorDomain.STORAGE,
145
+ category: ErrorCategory.THIRD_PARTY,
146
+ details: { tableName },
147
+ },
148
+ error,
149
+ );
150
+ this.logger.error(matstraError.message);
151
+ this.logger?.trackException(matstraError);
152
+ }
118
153
  }
119
154
  }
120
155
 
@@ -127,8 +162,15 @@ export class MongoDBStore extends MastraStorage {
127
162
  const collection = await this.getCollection(tableName);
128
163
  await collection.insertMany(records);
129
164
  } catch (error) {
130
- this.logger.error(`Error upserting into table ${tableName}: ${error}`);
131
- throw error;
165
+ throw new MastraError(
166
+ {
167
+ id: 'STORAGE_MONGODB_STORE_BATCH_INSERT_FAILED',
168
+ domain: ErrorDomain.STORAGE,
169
+ category: ErrorCategory.THIRD_PARTY,
170
+ details: { tableName },
171
+ },
172
+ error,
173
+ );
132
174
  }
133
175
  }
134
176
 
@@ -138,8 +180,15 @@ export class MongoDBStore extends MastraStorage {
138
180
  const collection = await this.getCollection(tableName);
139
181
  return (await collection.find(keys).toArray()) as R;
140
182
  } catch (error) {
141
- this.logger.error(`Error loading ${tableName} with keys ${JSON.stringify(keys)}: ${error}`);
142
- throw error;
183
+ throw new MastraError(
184
+ {
185
+ id: 'STORAGE_MONGODB_STORE_LOAD_FAILED',
186
+ domain: ErrorDomain.STORAGE,
187
+ category: ErrorCategory.THIRD_PARTY,
188
+ details: { tableName },
189
+ },
190
+ error,
191
+ );
143
192
  }
144
193
  }
145
194
 
@@ -156,8 +205,15 @@ export class MongoDBStore extends MastraStorage {
156
205
  metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
157
206
  };
158
207
  } catch (error) {
159
- this.logger.error(`Error loading thread with ID ${threadId}: ${error}`);
160
- throw error;
208
+ throw new MastraError(
209
+ {
210
+ id: 'STORAGE_MONGODB_STORE_GET_THREAD_BY_ID_FAILED',
211
+ domain: ErrorDomain.STORAGE,
212
+ category: ErrorCategory.THIRD_PARTY,
213
+ details: { threadId },
214
+ },
215
+ error,
216
+ );
161
217
  }
162
218
  }
163
219
 
@@ -174,8 +230,15 @@ export class MongoDBStore extends MastraStorage {
174
230
  metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
175
231
  }));
176
232
  } catch (error) {
177
- this.logger.error(`Error loading threads by resourceId ${resourceId}: ${error}`);
178
- throw error;
233
+ throw new MastraError(
234
+ {
235
+ id: 'STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
236
+ domain: ErrorDomain.STORAGE,
237
+ category: ErrorCategory.THIRD_PARTY,
238
+ details: { resourceId },
239
+ },
240
+ error,
241
+ );
179
242
  }
180
243
  }
181
244
 
@@ -194,8 +257,15 @@ export class MongoDBStore extends MastraStorage {
194
257
  );
195
258
  return thread;
196
259
  } catch (error) {
197
- this.logger.error(`Error saving thread ${thread.id}: ${error}`);
198
- throw error;
260
+ throw new MastraError(
261
+ {
262
+ id: 'STORAGE_MONGODB_STORE_SAVE_THREAD_FAILED',
263
+ domain: ErrorDomain.STORAGE,
264
+ category: ErrorCategory.THIRD_PARTY,
265
+ details: { threadId: thread.id },
266
+ },
267
+ error,
268
+ );
199
269
  }
200
270
  }
201
271
 
@@ -210,7 +280,13 @@ export class MongoDBStore extends MastraStorage {
210
280
  }): Promise<StorageThreadType> {
211
281
  const thread = await this.getThreadById({ threadId: id });
212
282
  if (!thread) {
213
- throw new Error(`Thread ${id} not found`);
283
+ throw new MastraError({
284
+ id: 'STORAGE_MONGODB_STORE_UPDATE_THREAD_NOT_FOUND',
285
+ domain: ErrorDomain.STORAGE,
286
+ category: ErrorCategory.THIRD_PARTY,
287
+ details: { threadId: id },
288
+ text: `Thread ${id} not found`,
289
+ });
214
290
  }
215
291
 
216
292
  const updatedThread = {
@@ -234,8 +310,15 @@ export class MongoDBStore extends MastraStorage {
234
310
  },
235
311
  );
236
312
  } catch (error) {
237
- this.logger.error(`Error updating thread ${id}:) ${error}`);
238
- throw error;
313
+ throw new MastraError(
314
+ {
315
+ id: 'STORAGE_MONGODB_STORE_UPDATE_THREAD_FAILED',
316
+ domain: ErrorDomain.STORAGE,
317
+ category: ErrorCategory.THIRD_PARTY,
318
+ details: { threadId: id },
319
+ },
320
+ error,
321
+ );
239
322
  }
240
323
 
241
324
  return updatedThread;
@@ -250,8 +333,15 @@ export class MongoDBStore extends MastraStorage {
250
333
  const collectionThreads = await this.getCollection(TABLE_THREADS);
251
334
  await collectionThreads.deleteOne({ id: threadId });
252
335
  } catch (error) {
253
- this.logger.error(`Error deleting thread ${threadId}: ${error}`);
254
- throw error;
336
+ throw new MastraError(
337
+ {
338
+ id: 'STORAGE_MONGODB_STORE_DELETE_THREAD_FAILED',
339
+ domain: ErrorDomain.STORAGE,
340
+ category: ErrorCategory.THIRD_PARTY,
341
+ details: { threadId },
342
+ },
343
+ error,
344
+ );
255
345
  }
256
346
  }
257
347
 
@@ -265,7 +355,7 @@ export class MongoDBStore extends MastraStorage {
265
355
  format?: 'v1' | 'v2';
266
356
  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
267
357
  try {
268
- const limit = typeof selectBy?.last === 'number' ? selectBy.last : 40;
358
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
269
359
  const include = selectBy?.include || [];
270
360
  let messages: MastraMessageV2[] = [];
271
361
  let allMessages: MastraMessageV2[] = [];
@@ -322,8 +412,15 @@ export class MongoDBStore extends MastraStorage {
322
412
  if (format === `v2`) return list.get.all.v2();
323
413
  return list.get.all.v1();
324
414
  } catch (error) {
325
- this.logger.error('Error getting messages:', error as Error);
326
- throw error;
415
+ throw new MastraError(
416
+ {
417
+ id: 'STORAGE_MONGODB_STORE_GET_MESSAGES_FAILED',
418
+ domain: ErrorDomain.STORAGE,
419
+ category: ErrorCategory.THIRD_PARTY,
420
+ details: { threadId },
421
+ },
422
+ error,
423
+ );
327
424
  }
328
425
  }
329
426
 
@@ -422,31 +519,42 @@ export class MongoDBStore extends MastraStorage {
422
519
  });
423
520
  }
424
521
 
425
- const collection = await this.getCollection(TABLE_TRACES);
426
- const result = await collection
427
- .find(query, {
428
- sort: { startTime: -1 },
429
- })
430
- .limit(limit)
431
- .skip(offset)
432
- .toArray();
433
-
434
- return result.map(row => ({
435
- id: row.id,
436
- parentSpanId: row.parentSpanId,
437
- traceId: row.traceId,
438
- name: row.name,
439
- scope: row.scope,
440
- kind: row.kind,
441
- status: safelyParseJSON(row.status as string),
442
- events: safelyParseJSON(row.events as string),
443
- links: safelyParseJSON(row.links as string),
444
- attributes: safelyParseJSON(row.attributes as string),
445
- startTime: row.startTime,
446
- endTime: row.endTime,
447
- other: safelyParseJSON(row.other as string),
448
- createdAt: row.createdAt,
449
- })) as any;
522
+ try {
523
+ const collection = await this.getCollection(TABLE_TRACES);
524
+ const result = await collection
525
+ .find(query, {
526
+ sort: { startTime: -1 },
527
+ })
528
+ .limit(limit)
529
+ .skip(offset)
530
+ .toArray();
531
+
532
+ return result.map(row => ({
533
+ id: row.id,
534
+ parentSpanId: row.parentSpanId,
535
+ traceId: row.traceId,
536
+ name: row.name,
537
+ scope: row.scope,
538
+ kind: row.kind,
539
+ status: safelyParseJSON(row.status as string),
540
+ events: safelyParseJSON(row.events as string),
541
+ links: safelyParseJSON(row.links as string),
542
+ attributes: safelyParseJSON(row.attributes as string),
543
+ startTime: row.startTime,
544
+ endTime: row.endTime,
545
+ other: safelyParseJSON(row.other as string),
546
+ createdAt: row.createdAt,
547
+ })) as any;
548
+ } catch (error) {
549
+ throw new MastraError(
550
+ {
551
+ id: 'STORAGE_MONGODB_STORE_GET_TRACES_FAILED',
552
+ domain: ErrorDomain.STORAGE,
553
+ category: ErrorCategory.THIRD_PARTY,
554
+ },
555
+ error,
556
+ );
557
+ }
450
558
  }
451
559
 
452
560
  async getWorkflowRuns({
@@ -486,46 +594,57 @@ export class MongoDBStore extends MastraStorage {
486
594
  }
487
595
  }
488
596
 
489
- const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
490
- let total = 0;
491
- // Only get total count when using pagination
492
- if (limit !== undefined && offset !== undefined) {
493
- total = await collection.countDocuments(query);
494
- }
597
+ try {
598
+ const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
599
+ let total = 0;
600
+ // Only get total count when using pagination
601
+ if (limit !== undefined && offset !== undefined) {
602
+ total = await collection.countDocuments(query);
603
+ }
495
604
 
496
- // Get results
497
- const request = collection.find(query).sort({ createdAt: 'desc' });
498
- if (limit) {
499
- request.limit(limit);
500
- }
605
+ // Get results
606
+ const request = collection.find(query).sort({ createdAt: 'desc' });
607
+ if (limit) {
608
+ request.limit(limit);
609
+ }
501
610
 
502
- if (offset) {
503
- request.skip(offset);
504
- }
611
+ if (offset) {
612
+ request.skip(offset);
613
+ }
505
614
 
506
- const result = await request.toArray();
507
- const runs = result.map(row => {
508
- let parsedSnapshot: WorkflowRunState | string = row.snapshot;
509
- if (typeof parsedSnapshot === 'string') {
510
- try {
511
- parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;
512
- } catch (e) {
513
- // If parsing fails, return the raw snapshot string
514
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
615
+ const result = await request.toArray();
616
+ const runs = result.map(row => {
617
+ let parsedSnapshot: WorkflowRunState | string = row.snapshot;
618
+ if (typeof parsedSnapshot === 'string') {
619
+ try {
620
+ parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;
621
+ } catch (e) {
622
+ // If parsing fails, return the raw snapshot string
623
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
624
+ }
515
625
  }
516
- }
517
626
 
518
- return {
519
- workflowName: row.workflow_name as string,
520
- runId: row.run_id as string,
521
- snapshot: parsedSnapshot,
522
- createdAt: new Date(row.createdAt as string),
523
- updatedAt: new Date(row.updatedAt as string),
524
- };
525
- });
627
+ return {
628
+ workflowName: row.workflow_name as string,
629
+ runId: row.run_id as string,
630
+ snapshot: parsedSnapshot,
631
+ createdAt: new Date(row.createdAt as string),
632
+ updatedAt: new Date(row.updatedAt as string),
633
+ };
634
+ });
526
635
 
527
- // Use runs.length as total when not paginating
528
- return { runs, total: total || runs.length };
636
+ // Use runs.length as total when not paginating
637
+ return { runs, total: total || runs.length };
638
+ } catch (error) {
639
+ throw new MastraError(
640
+ {
641
+ id: 'STORAGE_MONGODB_STORE_GET_WORKFLOW_RUNS_FAILED',
642
+ domain: ErrorDomain.STORAGE,
643
+ category: ErrorCategory.THIRD_PARTY,
644
+ },
645
+ error,
646
+ );
647
+ }
529
648
  }
530
649
 
531
650
  async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {
@@ -564,8 +683,15 @@ export class MongoDBStore extends MastraStorage {
564
683
  if (error instanceof Error && error.message.includes('no such table')) {
565
684
  return [];
566
685
  }
567
- this.logger.error('Failed to get evals for the specified agent: ' + (error as any)?.message);
568
- throw error;
686
+ throw new MastraError(
687
+ {
688
+ id: 'STORAGE_MONGODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
689
+ domain: ErrorDomain.STORAGE,
690
+ category: ErrorCategory.THIRD_PARTY,
691
+ details: { agentName },
692
+ },
693
+ error,
694
+ );
569
695
  }
570
696
  }
571
697
 
@@ -595,8 +721,15 @@ export class MongoDBStore extends MastraStorage {
595
721
  { upsert: true },
596
722
  );
597
723
  } catch (error) {
598
- this.logger.error(`Error persisting workflow snapshot: ${error}`);
599
- throw error;
724
+ throw new MastraError(
725
+ {
726
+ id: 'STORAGE_MONGODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED',
727
+ domain: ErrorDomain.STORAGE,
728
+ category: ErrorCategory.THIRD_PARTY,
729
+ details: { workflowName, runId },
730
+ },
731
+ error,
732
+ );
600
733
  }
601
734
  }
602
735
 
@@ -622,8 +755,15 @@ export class MongoDBStore extends MastraStorage {
622
755
 
623
756
  return JSON.parse(result[0].snapshot);
624
757
  } catch (error) {
625
- console.error('Error loading workflow snapshot:', error);
626
- throw error;
758
+ throw new MastraError(
759
+ {
760
+ id: 'STORAGE_MONGODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED',
761
+ domain: ErrorDomain.STORAGE,
762
+ category: ErrorCategory.THIRD_PARTY,
763
+ details: { workflowName, runId },
764
+ },
765
+ error,
766
+ );
627
767
  }
628
768
  }
629
769
 
@@ -652,8 +792,15 @@ export class MongoDBStore extends MastraStorage {
652
792
 
653
793
  return this.parseWorkflowRun(result);
654
794
  } catch (error) {
655
- console.error('Error getting workflow run by ID:', error);
656
- throw error;
795
+ throw new MastraError(
796
+ {
797
+ id: 'STORAGE_MONGODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
798
+ domain: ErrorDomain.STORAGE,
799
+ category: ErrorCategory.THIRD_PARTY,
800
+ details: { runId },
801
+ },
802
+ error,
803
+ );
657
804
  }
658
805
  }
659
806
 
@@ -721,7 +868,12 @@ export class MongoDBStore extends MastraStorage {
721
868
  }
722
869
 
723
870
  async getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
724
- throw new Error('Method not implemented.');
871
+ throw new MastraError({
872
+ id: 'STORAGE_MONGODB_STORE_GET_TRACES_PAGINATED_FAILED',
873
+ domain: ErrorDomain.STORAGE,
874
+ category: ErrorCategory.THIRD_PARTY,
875
+ text: 'Method not implemented.',
876
+ });
725
877
  }
726
878
 
727
879
  async getThreadsByResourceIdPaginated(_args: {
@@ -729,16 +881,48 @@ export class MongoDBStore extends MastraStorage {
729
881
  page?: number;
730
882
  perPage?: number;
731
883
  }): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
732
- throw new Error('Method not implemented.');
884
+ throw new MastraError({
885
+ id: 'STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED',
886
+ domain: ErrorDomain.STORAGE,
887
+ category: ErrorCategory.THIRD_PARTY,
888
+ text: 'Method not implemented.',
889
+ });
733
890
  }
734
891
 
735
892
  async getMessagesPaginated(
736
893
  _args: StorageGetMessagesArg,
737
894
  ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
738
- throw new Error('Method not implemented.');
895
+ throw new MastraError({
896
+ id: 'STORAGE_MONGODB_STORE_GET_MESSAGES_PAGINATED_FAILED',
897
+ domain: ErrorDomain.STORAGE,
898
+ category: ErrorCategory.THIRD_PARTY,
899
+ text: 'Method not implemented.',
900
+ });
739
901
  }
740
902
 
741
903
  async close(): Promise<void> {
742
- await this.#client.close();
904
+ try {
905
+ await this.#client.close();
906
+ } catch (error) {
907
+ throw new MastraError(
908
+ {
909
+ id: 'STORAGE_MONGODB_STORE_CLOSE_FAILED',
910
+ domain: ErrorDomain.STORAGE,
911
+ category: ErrorCategory.USER,
912
+ },
913
+ error,
914
+ );
915
+ }
916
+ }
917
+
918
+ async updateMessages(_args: {
919
+ messages: Partial<Omit<MastraMessageV2, 'createdAt'>> &
920
+ {
921
+ id: string;
922
+ content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
923
+ }[];
924
+ }): Promise<MastraMessageV2[]> {
925
+ this.logger.error('updateMessages is not yet implemented in MongoDBStore');
926
+ throw new Error('Method not implemented');
743
927
  }
744
928
  }