Skip to content

Commit 4fba706

Browse files
committed
feat(utils): enhance DexieStorageProvider with comprehensive error handling
Add robust error handling to critical storage operations: - Input validation for all required parameters - Structured error conversion using new error classes - Enhanced error logging with detailed context - Comprehensive error handling for createList, addEntityToList, addBookmark - Graceful error recovery with user-friendly error messages Improves data safety, debugging capabilities, and user experience.
1 parent a803541 commit 4fba706

File tree

1 file changed

+100
-13
lines changed

1 file changed

+100
-13
lines changed

packages/utils/src/storage/dexie-storage-provider.ts

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,52 @@ import type { GenericLogger } from '../logger.js';
1414
import type { CatalogueEntity,CatalogueList } from './catalogue-db.js';
1515
import { CatalogueService } from './catalogue-db.js';
1616
import type { AddBookmarkParams, AddEntityParams, AddToHistoryParams, BatchAddResult, CatalogueStorageProvider, CreateListParams, ListStats, ShareAccessResult } from './catalogue-storage-provider.js';
17+
import {
18+
ConnectionError,
19+
convertIndexedDBError,
20+
IndexedDBError,
21+
NotFoundError,
22+
OperationAbortedError,
23+
QuotaExceededError,
24+
ValidationError,
25+
} from './errors.js';
1726

1827
/**
1928
* Production storage provider using IndexedDB via Dexie
2029
* Delegates all operations to the existing CatalogueService
30+
* Enhanced with comprehensive error handling and logging
2131
*/
2232
export class DexieStorageProvider implements CatalogueStorageProvider {
2333
private catalogueService: CatalogueService;
34+
private logger?: GenericLogger;
2435

2536
constructor(logger?: GenericLogger) {
37+
this.logger = logger;
2638
this.catalogueService = new CatalogueService(logger);
2739
}
2840

2941
// ========== List Operations ==========
3042

3143
async createList(params: CreateListParams): Promise<string> {
32-
return await this.catalogueService.createList(params);
44+
try {
45+
// Validate input parameters
46+
if (!params.title || params.title.trim().length === 0) {
47+
throw new ValidationError('title', params.title, 'Title cannot be empty');
48+
}
49+
50+
const result = await this.catalogueService.createList(params);
51+
52+
this.logger?.info('storage', 'List created successfully', { listId: result, title: params.title });
53+
return result;
54+
} catch (error) {
55+
const storageError = convertIndexedDBError('createList', error);
56+
this.logger?.error('storage', 'Failed to create list', {
57+
error: storageError.message,
58+
title: params.title,
59+
originalError: error,
60+
});
61+
throw storageError;
62+
}
3363
}
3464

3565
async getList(listId: string): Promise<CatalogueList | null> {
@@ -54,13 +84,44 @@ export class DexieStorageProvider implements CatalogueStorageProvider {
5484
// ========== Entity Operations ==========
5585

5686
async addEntityToList(params: AddEntityParams): Promise<string> {
57-
return await this.catalogueService.addEntityToList({
58-
listId: params.listId,
59-
entityType: params.entityType,
60-
entityId: params.entityId,
61-
notes: params.notes,
62-
position: params.position,
63-
});
87+
try {
88+
// Validate input parameters
89+
if (!params.listId || params.listId.trim().length === 0) {
90+
throw new ValidationError('listId', params.listId, 'List ID cannot be empty');
91+
}
92+
if (!params.entityId || params.entityId.trim().length === 0) {
93+
throw new ValidationError('entityId', params.entityId, 'Entity ID cannot be empty');
94+
}
95+
if (!params.entityType) {
96+
throw new ValidationError('entityType', params.entityType, 'Entity type is required');
97+
}
98+
99+
const result = await this.catalogueService.addEntityToList({
100+
listId: params.listId,
101+
entityType: params.entityType,
102+
entityId: params.entityId,
103+
notes: params.notes,
104+
position: params.position,
105+
});
106+
107+
this.logger?.info('storage', 'Entity added to list successfully', {
108+
entityId: params.entityId,
109+
entityType: params.entityType,
110+
listId: params.listId,
111+
recordId: result,
112+
});
113+
return result;
114+
} catch (error) {
115+
const storageError = convertIndexedDBError('addEntityToList', error);
116+
this.logger?.error('storage', 'Failed to add entity to list', {
117+
error: storageError.message,
118+
entityId: params.entityId,
119+
entityType: params.entityType,
120+
listId: params.listId,
121+
originalError: error,
122+
});
123+
throw storageError;
124+
}
64125
}
65126

66127
async getListEntities(listId: string): Promise<CatalogueEntity[]> {
@@ -133,11 +194,37 @@ export class DexieStorageProvider implements CatalogueStorageProvider {
133194
}
134195

135196
async addBookmark(params: AddBookmarkParams): Promise<string> {
136-
return await this.catalogueService.addBookmark({
137-
entityType: params.entityType,
138-
entityId: params.entityId,
139-
notes: params.notes,
140-
});
197+
try {
198+
// Validate input parameters
199+
if (!params.entityId || params.entityId.trim().length === 0) {
200+
throw new ValidationError('entityId', params.entityId, 'Entity ID cannot be empty');
201+
}
202+
if (!params.entityType) {
203+
throw new ValidationError('entityType', params.entityType, 'Entity type is required');
204+
}
205+
206+
const result = await this.catalogueService.addBookmark({
207+
entityType: params.entityType,
208+
entityId: params.entityId,
209+
notes: params.notes,
210+
});
211+
212+
this.logger?.info('storage', 'Bookmark added successfully', {
213+
entityId: params.entityId,
214+
entityType: params.entityType,
215+
recordId: result,
216+
});
217+
return result;
218+
} catch (error) {
219+
const storageError = convertIndexedDBError('addBookmark', error);
220+
this.logger?.error('storage', 'Failed to add bookmark', {
221+
error: storageError.message,
222+
entityId: params.entityId,
223+
entityType: params.entityType,
224+
originalError: error,
225+
});
226+
throw storageError;
227+
}
141228
}
142229

143230
async removeBookmark(entityRecordId: string): Promise<void> {

0 commit comments

Comments
 (0)