@mastra/libsql 0.10.3 → 0.10.4-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.
@@ -1,7 +1,8 @@
1
1
  import { createClient } from '@libsql/client';
2
2
  import type { Client, InValue } from '@libsql/client';
3
3
  import { MessageList } from '@mastra/core/agent';
4
- import type { MastraMessageV2 } from '@mastra/core/agent';
4
+ import type { MastraMessageContentV2, MastraMessageV2 } from '@mastra/core/agent';
5
+ import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
5
6
  import type { MetricResult, TestInfo } from '@mastra/core/eval';
6
7
  import type { MastraMessageV1, StorageThreadType } from '@mastra/core/memory';
7
8
  import {
@@ -128,8 +129,19 @@ export class LibSQLStore extends MastraStorage {
128
129
  const sql = this.getCreateTableSQL(tableName, schema);
129
130
  await this.client.execute(sql);
130
131
  } catch (error) {
131
- this.logger.error(`Error creating table ${tableName}: ${error}`);
132
- throw error;
132
+ // this.logger.error(`Error creating table ${tableName}: ${error}`);
133
+ // throw error;
134
+ throw new MastraError(
135
+ {
136
+ id: 'LIBSQL_STORE_CREATE_TABLE_FAILED',
137
+ domain: ErrorDomain.STORAGE,
138
+ category: ErrorCategory.THIRD_PARTY,
139
+ details: {
140
+ tableName,
141
+ },
142
+ },
143
+ error,
144
+ );
133
145
  }
134
146
  }
135
147
 
@@ -183,10 +195,17 @@ export class LibSQLStore extends MastraStorage {
183
195
  }
184
196
  }
185
197
  } catch (error) {
186
- this.logger?.error?.(
187
- `Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`,
198
+ throw new MastraError(
199
+ {
200
+ id: 'LIBSQL_STORE_ALTER_TABLE_FAILED',
201
+ domain: ErrorDomain.STORAGE,
202
+ category: ErrorCategory.THIRD_PARTY,
203
+ details: {
204
+ tableName,
205
+ },
206
+ },
207
+ error,
188
208
  );
189
- throw new Error(`Failed to alter table ${tableName}: ${error}`);
190
209
  }
191
210
  }
192
211
 
@@ -195,9 +214,19 @@ export class LibSQLStore extends MastraStorage {
195
214
  try {
196
215
  await this.client.execute(`DELETE FROM ${parsedTableName}`);
197
216
  } catch (e) {
198
- if (e instanceof Error) {
199
- this.logger.error(e.message);
200
- }
217
+ const mastraError = new MastraError(
218
+ {
219
+ id: 'LIBSQL_STORE_CLEAR_TABLE_FAILED',
220
+ domain: ErrorDomain.STORAGE,
221
+ category: ErrorCategory.THIRD_PARTY,
222
+ details: {
223
+ tableName,
224
+ },
225
+ },
226
+ e,
227
+ );
228
+ this.logger?.trackException?.(mastraError);
229
+ this.logger?.error?.(mastraError.toString());
201
230
  }
202
231
  }
203
232
 
@@ -277,7 +306,19 @@ export class LibSQLStore extends MastraStorage {
277
306
  return this.executeWriteOperationWithRetry(
278
307
  () => this.doBatchInsert(args),
279
308
  `batch insert into table ${args.tableName}`,
280
- );
309
+ ).catch(error => {
310
+ throw new MastraError(
311
+ {
312
+ id: 'LIBSQL_STORE_BATCH_INSERT_FAILED',
313
+ domain: ErrorDomain.STORAGE,
314
+ category: ErrorCategory.THIRD_PARTY,
315
+ details: {
316
+ tableName: args.tableName,
317
+ },
318
+ },
319
+ error,
320
+ );
321
+ });
281
322
  }
282
323
 
283
324
  private async doBatchInsert({
@@ -327,19 +368,31 @@ export class LibSQLStore extends MastraStorage {
327
368
  }
328
369
 
329
370
  async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
330
- const result = await this.load<StorageThreadType>({
331
- tableName: TABLE_THREADS,
332
- keys: { id: threadId },
333
- });
371
+ try {
372
+ const result = await this.load<StorageThreadType>({
373
+ tableName: TABLE_THREADS,
374
+ keys: { id: threadId },
375
+ });
334
376
 
335
- if (!result) {
336
- return null;
337
- }
377
+ if (!result) {
378
+ return null;
379
+ }
338
380
 
339
- return {
340
- ...result,
341
- metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
342
- };
381
+ return {
382
+ ...result,
383
+ metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
384
+ };
385
+ } catch (error) {
386
+ throw new MastraError(
387
+ {
388
+ id: 'LIBSQL_STORE_GET_THREAD_BY_ID_FAILED',
389
+ domain: ErrorDomain.STORAGE,
390
+ category: ErrorCategory.THIRD_PARTY,
391
+ details: { threadId },
392
+ },
393
+ error,
394
+ );
395
+ }
343
396
  }
344
397
 
345
398
  /**
@@ -372,7 +425,17 @@ export class LibSQLStore extends MastraStorage {
372
425
  }
373
426
  return result.rows.map(mapRowToStorageThreadType);
374
427
  } catch (error) {
375
- this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
428
+ const mastraError = new MastraError(
429
+ {
430
+ id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
431
+ domain: ErrorDomain.STORAGE,
432
+ category: ErrorCategory.THIRD_PARTY,
433
+ details: { resourceId },
434
+ },
435
+ error,
436
+ );
437
+ this.logger?.trackException?.(mastraError);
438
+ this.logger?.error?.(mastraError.toString());
376
439
  return [];
377
440
  }
378
441
  }
@@ -430,21 +493,46 @@ export class LibSQLStore extends MastraStorage {
430
493
  hasMore: currentOffset + threads.length < total,
431
494
  };
432
495
  } catch (error) {
433
- this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
496
+ const mastraError = new MastraError(
497
+ {
498
+ id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
499
+ domain: ErrorDomain.STORAGE,
500
+ category: ErrorCategory.THIRD_PARTY,
501
+ details: { resourceId },
502
+ },
503
+ error,
504
+ );
505
+ this.logger?.trackException?.(mastraError);
506
+ this.logger?.error?.(mastraError.toString());
434
507
  return { threads: [], total: 0, page, perPage, hasMore: false };
435
508
  }
436
509
  }
437
510
 
438
511
  async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
439
- await this.insert({
440
- tableName: TABLE_THREADS,
441
- record: {
442
- ...thread,
443
- metadata: JSON.stringify(thread.metadata),
444
- },
445
- });
512
+ try {
513
+ await this.insert({
514
+ tableName: TABLE_THREADS,
515
+ record: {
516
+ ...thread,
517
+ metadata: JSON.stringify(thread.metadata),
518
+ },
519
+ });
446
520
 
447
- return thread;
521
+ return thread;
522
+ } catch (error) {
523
+ const mastraError = new MastraError(
524
+ {
525
+ id: 'LIBSQL_STORE_SAVE_THREAD_FAILED',
526
+ domain: ErrorDomain.STORAGE,
527
+ category: ErrorCategory.THIRD_PARTY,
528
+ details: { threadId: thread.id },
529
+ },
530
+ error,
531
+ );
532
+ this.logger?.trackException?.(mastraError);
533
+ this.logger?.error?.(mastraError.toString());
534
+ throw mastraError;
535
+ }
448
536
  }
449
537
 
450
538
  async updateThread({
@@ -458,7 +546,13 @@ export class LibSQLStore extends MastraStorage {
458
546
  }): Promise<StorageThreadType> {
459
547
  const thread = await this.getThreadById({ threadId: id });
460
548
  if (!thread) {
461
- throw new Error(`Thread ${id} not found`);
549
+ throw new MastraError({
550
+ id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED_THREAD_NOT_FOUND',
551
+ domain: ErrorDomain.STORAGE,
552
+ category: ErrorCategory.USER,
553
+ text: `Thread ${id} not found`,
554
+ details: { threadId: id },
555
+ });
462
556
  }
463
557
 
464
558
  const updatedThread = {
@@ -470,24 +564,49 @@ export class LibSQLStore extends MastraStorage {
470
564
  },
471
565
  };
472
566
 
473
- await this.client.execute({
474
- sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
475
- args: [title, JSON.stringify(updatedThread.metadata), id],
476
- });
567
+ try {
568
+ await this.client.execute({
569
+ sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
570
+ args: [title, JSON.stringify(updatedThread.metadata), id],
571
+ });
477
572
 
478
- return updatedThread;
573
+ return updatedThread;
574
+ } catch (error) {
575
+ throw new MastraError(
576
+ {
577
+ id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED',
578
+ domain: ErrorDomain.STORAGE,
579
+ category: ErrorCategory.THIRD_PARTY,
580
+ text: `Failed to update thread ${id}`,
581
+ details: { threadId: id },
582
+ },
583
+ error,
584
+ );
585
+ }
479
586
  }
480
587
 
481
588
  async deleteThread({ threadId }: { threadId: string }): Promise<void> {
482
589
  // Delete messages for this thread (manual step)
483
- await this.client.execute({
484
- sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
485
- args: [threadId],
486
- });
487
- await this.client.execute({
488
- sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
489
- args: [threadId],
490
- });
590
+ try {
591
+ await this.client.execute({
592
+ sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
593
+ args: [threadId],
594
+ });
595
+ await this.client.execute({
596
+ sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
597
+ args: [threadId],
598
+ });
599
+ } catch (error) {
600
+ throw new MastraError(
601
+ {
602
+ id: 'LIBSQL_STORE_DELETE_THREAD_FAILED',
603
+ domain: ErrorDomain.STORAGE,
604
+ category: ErrorCategory.THIRD_PARTY,
605
+ details: { threadId },
606
+ },
607
+ error,
608
+ );
609
+ }
491
610
  // TODO: Need to check if CASCADE is enabled so that messages will be automatically deleted due to CASCADE constraint
492
611
  }
493
612
 
@@ -577,8 +696,7 @@ export class LibSQLStore extends MastraStorage {
577
696
  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
578
697
  try {
579
698
  const messages: MastraMessageV2[] = [];
580
- const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
581
-
699
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
582
700
  if (selectBy?.include?.length) {
583
701
  const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
584
702
  if (includeMessages) {
@@ -612,8 +730,15 @@ export class LibSQLStore extends MastraStorage {
612
730
  if (format === `v2`) return list.get.all.v2();
613
731
  return list.get.all.v1();
614
732
  } catch (error) {
615
- this.logger.error('Error getting messages:', error as Error);
616
- throw error;
733
+ throw new MastraError(
734
+ {
735
+ id: 'LIBSQL_STORE_GET_MESSAGES_FAILED',
736
+ domain: ErrorDomain.STORAGE,
737
+ category: ErrorCategory.THIRD_PARTY,
738
+ details: { threadId },
739
+ },
740
+ error,
741
+ );
617
742
  }
618
743
  }
619
744
 
@@ -630,9 +755,21 @@ export class LibSQLStore extends MastraStorage {
630
755
  const messages: MastraMessageV2[] = [];
631
756
 
632
757
  if (selectBy?.include?.length) {
633
- const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
634
- if (includeMessages) {
635
- messages.push(...includeMessages);
758
+ try {
759
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
760
+ if (includeMessages) {
761
+ messages.push(...includeMessages);
762
+ }
763
+ } catch (error) {
764
+ throw new MastraError(
765
+ {
766
+ id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED',
767
+ domain: ErrorDomain.STORAGE,
768
+ category: ErrorCategory.THIRD_PARTY,
769
+ details: { threadId },
770
+ },
771
+ error,
772
+ );
636
773
  }
637
774
  }
638
775
 
@@ -688,7 +825,17 @@ export class LibSQLStore extends MastraStorage {
688
825
  hasMore: currentOffset + messages.length < total,
689
826
  };
690
827
  } catch (error) {
691
- this.logger.error('Error getting paginated messages:', error as Error);
828
+ const mastraError = new MastraError(
829
+ {
830
+ id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_FAILED',
831
+ domain: ErrorDomain.STORAGE,
832
+ category: ErrorCategory.THIRD_PARTY,
833
+ details: { threadId },
834
+ },
835
+ error,
836
+ );
837
+ this.logger?.trackException?.(mastraError);
838
+ this.logger?.error?.(mastraError.toString());
692
839
  return { messages: [], total: 0, page, perPage, hasMore: false };
693
840
  }
694
841
  }
@@ -750,11 +897,123 @@ export class LibSQLStore extends MastraStorage {
750
897
  if (format === `v2`) return list.get.all.v2();
751
898
  return list.get.all.v1();
752
899
  } catch (error) {
753
- this.logger.error('Failed to save messages in database: ' + (error as { message: string })?.message);
754
- throw error;
900
+ throw new MastraError(
901
+ {
902
+ id: 'LIBSQL_STORE_SAVE_MESSAGES_FAILED',
903
+ domain: ErrorDomain.STORAGE,
904
+ category: ErrorCategory.THIRD_PARTY,
905
+ },
906
+ error,
907
+ );
755
908
  }
756
909
  }
757
910
 
911
+ async updateMessages({
912
+ messages,
913
+ }: {
914
+ messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {
915
+ id: string;
916
+ content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
917
+ })[];
918
+ }): Promise<MastraMessageV2[]> {
919
+ if (messages.length === 0) {
920
+ return [];
921
+ }
922
+
923
+ const messageIds = messages.map(m => m.id);
924
+ const placeholders = messageIds.map(() => '?').join(',');
925
+
926
+ const selectSql = `SELECT * FROM ${TABLE_MESSAGES} WHERE id IN (${placeholders})`;
927
+ const existingResult = await this.client.execute({ sql: selectSql, args: messageIds });
928
+ const existingMessages: MastraMessageV2[] = existingResult.rows.map(row => this.parseRow(row));
929
+
930
+ if (existingMessages.length === 0) {
931
+ return [];
932
+ }
933
+
934
+ const batchStatements = [];
935
+ const threadIdsToUpdate = new Set<string>();
936
+ const columnMapping: Record<string, string> = {
937
+ threadId: 'thread_id',
938
+ };
939
+
940
+ for (const existingMessage of existingMessages) {
941
+ const updatePayload = messages.find(m => m.id === existingMessage.id);
942
+ if (!updatePayload) continue;
943
+
944
+ const { id, ...fieldsToUpdate } = updatePayload;
945
+ if (Object.keys(fieldsToUpdate).length === 0) continue;
946
+
947
+ threadIdsToUpdate.add(existingMessage.threadId!);
948
+ if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
949
+ threadIdsToUpdate.add(updatePayload.threadId);
950
+ }
951
+
952
+ const setClauses = [];
953
+ const args: InValue[] = [];
954
+ const updatableFields = { ...fieldsToUpdate };
955
+
956
+ // Special handling for the 'content' field to merge instead of overwrite
957
+ if (updatableFields.content) {
958
+ const newContent = {
959
+ ...existingMessage.content,
960
+ ...updatableFields.content,
961
+ // Deep merge metadata if it exists on both
962
+ ...(existingMessage.content?.metadata && updatableFields.content.metadata
963
+ ? {
964
+ metadata: {
965
+ ...existingMessage.content.metadata,
966
+ ...updatableFields.content.metadata,
967
+ },
968
+ }
969
+ : {}),
970
+ };
971
+ setClauses.push(`${parseSqlIdentifier('content', 'column name')} = ?`);
972
+ args.push(JSON.stringify(newContent));
973
+ delete updatableFields.content;
974
+ }
975
+
976
+ for (const key in updatableFields) {
977
+ if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
978
+ const dbKey = columnMapping[key] || key;
979
+ setClauses.push(`${parseSqlIdentifier(dbKey, 'column name')} = ?`);
980
+ let value = updatableFields[key as keyof typeof updatableFields];
981
+
982
+ if (typeof value === 'object' && value !== null) {
983
+ value = JSON.stringify(value);
984
+ }
985
+ args.push(value as InValue);
986
+ }
987
+ }
988
+
989
+ if (setClauses.length === 0) continue;
990
+
991
+ args.push(id);
992
+
993
+ const sql = `UPDATE ${TABLE_MESSAGES} SET ${setClauses.join(', ')} WHERE id = ?`;
994
+ batchStatements.push({ sql, args });
995
+ }
996
+
997
+ if (batchStatements.length === 0) {
998
+ return existingMessages;
999
+ }
1000
+
1001
+ const now = new Date().toISOString();
1002
+ for (const threadId of threadIdsToUpdate) {
1003
+ if (threadId) {
1004
+ batchStatements.push({
1005
+ sql: `UPDATE ${TABLE_THREADS} SET updatedAt = ? WHERE id = ?`,
1006
+ args: [now, threadId],
1007
+ });
1008
+ }
1009
+ }
1010
+
1011
+ await this.client.batch(batchStatements, 'write');
1012
+
1013
+ const updatedResult = await this.client.execute({ sql: selectSql, args: messageIds });
1014
+ return updatedResult.rows.map(row => this.parseRow(row));
1015
+ }
1016
+
758
1017
  private transformEvalRow(row: Record<string, any>): EvalRow {
759
1018
  const resultValue = JSON.parse(row.result as string);
760
1019
  const testInfoValue = row.test_info ? JSON.parse(row.test_info as string) : undefined;
@@ -799,8 +1058,15 @@ export class LibSQLStore extends MastraStorage {
799
1058
  if (error instanceof Error && error.message.includes('no such table')) {
800
1059
  return [];
801
1060
  }
802
- this.logger.error('Failed to get evals for the specified agent: ' + (error as any)?.message);
803
- throw error;
1061
+ throw new MastraError(
1062
+ {
1063
+ id: 'LIBSQL_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
1064
+ domain: ErrorDomain.STORAGE,
1065
+ category: ErrorCategory.THIRD_PARTY,
1066
+ details: { agentName },
1067
+ },
1068
+ error,
1069
+ );
804
1070
  }
805
1071
  }
806
1072
 
@@ -840,37 +1106,48 @@ export class LibSQLStore extends MastraStorage {
840
1106
 
841
1107
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
842
1108
 
843
- const countResult = await this.client.execute({
844
- sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
845
- args: queryParams,
846
- });
847
- const total = Number(countResult.rows?.[0]?.count ?? 0);
1109
+ try {
1110
+ const countResult = await this.client.execute({
1111
+ sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
1112
+ args: queryParams,
1113
+ });
1114
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
848
1115
 
849
- const currentOffset = page * perPage;
850
- const hasMore = currentOffset + perPage < total;
1116
+ const currentOffset = page * perPage;
1117
+ const hasMore = currentOffset + perPage < total;
1118
+
1119
+ if (total === 0) {
1120
+ return {
1121
+ evals: [],
1122
+ total: 0,
1123
+ page,
1124
+ perPage,
1125
+ hasMore: false,
1126
+ };
1127
+ }
1128
+
1129
+ const dataResult = await this.client.execute({
1130
+ sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
1131
+ args: [...queryParams, perPage, currentOffset],
1132
+ });
851
1133
 
852
- if (total === 0) {
853
1134
  return {
854
- evals: [],
855
- total: 0,
1135
+ evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
1136
+ total,
856
1137
  page,
857
1138
  perPage,
858
- hasMore: false,
1139
+ hasMore,
859
1140
  };
1141
+ } catch (error) {
1142
+ throw new MastraError(
1143
+ {
1144
+ id: 'LIBSQL_STORE_GET_EVALS_FAILED',
1145
+ domain: ErrorDomain.STORAGE,
1146
+ category: ErrorCategory.THIRD_PARTY,
1147
+ },
1148
+ error,
1149
+ );
860
1150
  }
861
-
862
- const dataResult = await this.client.execute({
863
- sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
864
- args: [...queryParams, perPage, currentOffset],
865
- });
866
-
867
- return {
868
- evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
869
- total,
870
- page,
871
- perPage,
872
- hasMore,
873
- };
874
1151
  }
875
1152
 
876
1153
  /**
@@ -892,8 +1169,19 @@ export class LibSQLStore extends MastraStorage {
892
1169
  end: args.toDate,
893
1170
  };
894
1171
  }
895
- const result = await this.getTracesPaginated(args);
896
- return result.traces;
1172
+ try {
1173
+ const result = await this.getTracesPaginated(args);
1174
+ return result.traces;
1175
+ } catch (error) {
1176
+ throw new MastraError(
1177
+ {
1178
+ id: 'LIBSQL_STORE_GET_TRACES_FAILED',
1179
+ domain: ErrorDomain.STORAGE,
1180
+ category: ErrorCategory.THIRD_PARTY,
1181
+ },
1182
+ error,
1183
+ );
1184
+ }
897
1185
  }
898
1186
 
899
1187
  public async getTracesPaginated(
@@ -943,55 +1231,66 @@ export class LibSQLStore extends MastraStorage {
943
1231
 
944
1232
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
945
1233
 
946
- const countResult = await this.client.execute({
947
- sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
948
- args: queryArgs,
949
- });
950
- const total = Number(countResult.rows?.[0]?.count ?? 0);
1234
+ try {
1235
+ const countResult = await this.client.execute({
1236
+ sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
1237
+ args: queryArgs,
1238
+ });
1239
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
1240
+
1241
+ if (total === 0) {
1242
+ return {
1243
+ traces: [],
1244
+ total: 0,
1245
+ page,
1246
+ perPage,
1247
+ hasMore: false,
1248
+ };
1249
+ }
1250
+
1251
+ const dataResult = await this.client.execute({
1252
+ sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
1253
+ args: [...queryArgs, perPage, currentOffset],
1254
+ });
1255
+
1256
+ const traces =
1257
+ dataResult.rows?.map(
1258
+ row =>
1259
+ ({
1260
+ id: row.id,
1261
+ parentSpanId: row.parentSpanId,
1262
+ traceId: row.traceId,
1263
+ name: row.name,
1264
+ scope: row.scope,
1265
+ kind: row.kind,
1266
+ status: safelyParseJSON(row.status as string),
1267
+ events: safelyParseJSON(row.events as string),
1268
+ links: safelyParseJSON(row.links as string),
1269
+ attributes: safelyParseJSON(row.attributes as string),
1270
+ startTime: row.startTime,
1271
+ endTime: row.endTime,
1272
+ other: safelyParseJSON(row.other as string),
1273
+ createdAt: row.createdAt,
1274
+ }) as Trace,
1275
+ ) ?? [];
951
1276
 
952
- if (total === 0) {
953
1277
  return {
954
- traces: [],
955
- total: 0,
1278
+ traces,
1279
+ total,
956
1280
  page,
957
1281
  perPage,
958
- hasMore: false,
1282
+ hasMore: currentOffset + traces.length < total,
959
1283
  };
1284
+ } catch (error) {
1285
+ throw new MastraError(
1286
+ {
1287
+ id: 'LIBSQL_STORE_GET_TRACES_PAGINATED_FAILED',
1288
+ domain: ErrorDomain.STORAGE,
1289
+ category: ErrorCategory.THIRD_PARTY,
1290
+ },
1291
+ error,
1292
+ );
960
1293
  }
961
-
962
- const dataResult = await this.client.execute({
963
- sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
964
- args: [...queryArgs, perPage, currentOffset],
965
- });
966
-
967
- const traces =
968
- dataResult.rows?.map(
969
- row =>
970
- ({
971
- id: row.id,
972
- parentSpanId: row.parentSpanId,
973
- traceId: row.traceId,
974
- name: row.name,
975
- scope: row.scope,
976
- kind: row.kind,
977
- status: safelyParseJSON(row.status as string),
978
- events: safelyParseJSON(row.events as string),
979
- links: safelyParseJSON(row.links as string),
980
- attributes: safelyParseJSON(row.attributes as string),
981
- startTime: row.startTime,
982
- endTime: row.endTime,
983
- other: safelyParseJSON(row.other as string),
984
- createdAt: row.createdAt,
985
- }) as Trace,
986
- ) ?? [];
987
-
988
- return {
989
- traces,
990
- total,
991
- page,
992
- perPage,
993
- hasMore: currentOffset + traces.length < total,
994
- };
995
1294
  }
996
1295
 
997
1296
  async getWorkflowRuns({
@@ -1061,8 +1360,14 @@ export class LibSQLStore extends MastraStorage {
1061
1360
  // Use runs.length as total when not paginating
1062
1361
  return { runs, total: total || runs.length };
1063
1362
  } catch (error) {
1064
- console.error('Error getting workflow runs:', error);
1065
- throw error;
1363
+ throw new MastraError(
1364
+ {
1365
+ id: 'LIBSQL_STORE_GET_WORKFLOW_RUNS_FAILED',
1366
+ domain: ErrorDomain.STORAGE,
1367
+ category: ErrorCategory.THIRD_PARTY,
1368
+ },
1369
+ error,
1370
+ );
1066
1371
  }
1067
1372
  }
1068
1373
 
@@ -1088,16 +1393,27 @@ export class LibSQLStore extends MastraStorage {
1088
1393
 
1089
1394
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
1090
1395
 
1091
- const result = await this.client.execute({
1092
- sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
1093
- args,
1094
- });
1396
+ try {
1397
+ const result = await this.client.execute({
1398
+ sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
1399
+ args,
1400
+ });
1095
1401
 
1096
- if (!result.rows?.[0]) {
1097
- return null;
1098
- }
1402
+ if (!result.rows?.[0]) {
1403
+ return null;
1404
+ }
1099
1405
 
1100
- return this.parseWorkflowRun(result.rows[0]);
1406
+ return this.parseWorkflowRun(result.rows[0]);
1407
+ } catch (error) {
1408
+ throw new MastraError(
1409
+ {
1410
+ id: 'LIBSQL_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
1411
+ domain: ErrorDomain.STORAGE,
1412
+ category: ErrorCategory.THIRD_PARTY,
1413
+ },
1414
+ error,
1415
+ );
1416
+ }
1101
1417
  }
1102
1418
 
1103
1419
  private async hasColumn(table: string, column: string): Promise<boolean> {