@prmichaelsen/remember-mcp 2.0.0 → 2.0.2

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.
@@ -6,6 +6,7 @@
6
6
  import type { Memory, ContentType, Location, MemoryContext } from '../types/memory.js';
7
7
  import { ensureMemoryCollection, getMemoryCollection } from '../weaviate/schema.js';
8
8
  import { logger } from '../utils/logger.js';
9
+ import { handleToolError } from '../utils/error-handler.js';
9
10
  import { DEFAULT_CONTENT_TYPE, getContentTypeDescription, isValidContentType } from '../constants/content-types.js';
10
11
 
11
12
  /**
@@ -196,7 +197,12 @@ export async function handleCreateMemory(
196
197
 
197
198
  return JSON.stringify(response, null, 2);
198
199
  } catch (error) {
199
- logger.error('Failed to create memory:', error);
200
- throw new Error(`Failed to create memory: ${error instanceof Error ? error.message : String(error)}`);
200
+ handleToolError(error, {
201
+ toolName: 'remember_create_memory',
202
+ operation: 'create memory',
203
+ userId,
204
+ contentType: args.type,
205
+ hasContent: !!args.content,
206
+ });
201
207
  }
202
208
  }
@@ -6,6 +6,7 @@
6
6
  import type { Memory, MemoryUpdate } from '../types/memory.js';
7
7
  import { getMemoryCollection } from '../weaviate/schema.js';
8
8
  import { logger } from '../utils/logger.js';
9
+ import { handleToolError, withErrorHandling } from '../utils/error-handler.js';
9
10
  import { isValidContentType } from '../constants/content-types.js';
10
11
 
11
12
  /**
@@ -113,12 +114,24 @@ export async function handleUpdateMemory(
113
114
  const collection = getMemoryCollection(userId);
114
115
 
115
116
  // Get existing memory to verify ownership and get current version
116
- const existingMemory = await collection.query.fetchObjectById(args.memory_id, {
117
- returnProperties: ['user_id', 'doc_type', 'version', 'type', 'weight', 'base_weight'],
118
- });
117
+ let existingMemory;
118
+ try {
119
+ existingMemory = await collection.query.fetchObjectById(args.memory_id, {
120
+ returnProperties: ['user_id', 'doc_type', 'version', 'type', 'weight', 'base_weight'],
121
+ });
122
+ } catch (fetchError) {
123
+ const fetchErrorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
124
+ logger.error('Failed to fetch memory for update:', {
125
+ error: fetchErrorMsg,
126
+ userId,
127
+ memoryId: args.memory_id,
128
+ collectionName: `Memory_${userId}`,
129
+ });
130
+ throw new Error(`Failed to fetch memory ${args.memory_id}: ${fetchErrorMsg}`);
131
+ }
119
132
 
120
133
  if (!existingMemory) {
121
- throw new Error(`Memory not found: ${args.memory_id}`);
134
+ throw new Error(`Memory not found: ${args.memory_id}. It may have been deleted or never existed.`);
122
135
  }
123
136
 
124
137
  // Verify ownership
@@ -202,10 +215,22 @@ export async function handleUpdateMemory(
202
215
  updates.version = (existingMemory.properties.version as number) + 1;
203
216
 
204
217
  // Perform update in Weaviate
205
- await collection.data.update({
206
- id: args.memory_id,
207
- properties: updates,
208
- });
218
+ try {
219
+ await collection.data.update({
220
+ id: args.memory_id,
221
+ properties: updates,
222
+ });
223
+ } catch (updateError) {
224
+ const updateErrorMsg = updateError instanceof Error ? updateError.message : String(updateError);
225
+ logger.error('Failed to perform Weaviate update:', {
226
+ error: updateErrorMsg,
227
+ userId,
228
+ memoryId: args.memory_id,
229
+ updateFields: Object.keys(updates),
230
+ collectionName: `Memory_${userId}`,
231
+ });
232
+ throw new Error(`Failed to update memory in Weaviate: ${updateErrorMsg}`);
233
+ }
209
234
 
210
235
  logger.info('Memory updated successfully', {
211
236
  userId,
@@ -224,7 +249,22 @@ export async function handleUpdateMemory(
224
249
 
225
250
  return JSON.stringify(result, null, 2);
226
251
  } catch (error) {
227
- logger.error('Failed to update memory:', error);
228
- throw new Error(`Failed to update memory: ${error instanceof Error ? error.message : String(error)}`);
252
+ const errorMessage = error instanceof Error ? error.message : String(error);
253
+ const errorStack = error instanceof Error ? error.stack : undefined;
254
+
255
+ logger.error('Failed to update memory:', {
256
+ error: errorMessage,
257
+ stack: errorStack,
258
+ userId,
259
+ memoryId: args.memory_id,
260
+ providedFields: Object.keys(args).filter(k => k !== 'memory_id'),
261
+ });
262
+
263
+ // Include detailed error information for debugging
264
+ throw new Error(
265
+ `Failed to update memory: ${errorMessage}` +
266
+ (errorStack ? `\n\nStack trace:\n${errorStack}` : '') +
267
+ `\n\nContext: userId=${userId}, memoryId=${args.memory_id}`
268
+ );
229
269
  }
230
270
  }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Centralized error handling utilities for MCP tools
3
+ * Provides consistent error logging and formatting across all tools
4
+ */
5
+
6
+ import { logger } from './logger.js';
7
+
8
+ /**
9
+ * Error context for detailed logging
10
+ */
11
+ export interface ErrorContext {
12
+ toolName: string;
13
+ userId?: string;
14
+ operation?: string;
15
+ [key: string]: any;
16
+ }
17
+
18
+ /**
19
+ * Format error with detailed context for logging and throwing
20
+ *
21
+ * @param error - The caught error
22
+ * @param context - Additional context about where/why the error occurred
23
+ * @returns Formatted error message with stack trace and context
24
+ */
25
+ export function formatDetailedError(error: unknown, context: ErrorContext): string {
26
+ const errorMessage = error instanceof Error ? error.message : String(error);
27
+ const errorStack = error instanceof Error ? error.stack : undefined;
28
+
29
+ // Log detailed error information
30
+ logger.error(`${context.toolName} failed:`, {
31
+ error: errorMessage,
32
+ stack: errorStack,
33
+ ...context,
34
+ });
35
+
36
+ // Build detailed error message
37
+ const contextStr = Object.entries(context)
38
+ .filter(([key]) => key !== 'toolName')
39
+ .map(([key, value]) => `${key}=${value}`)
40
+ .join(', ');
41
+
42
+ return (
43
+ `Failed to ${context.operation || 'execute'}: ${errorMessage}` +
44
+ (errorStack ? `\n\nStack trace:\n${errorStack}` : '') +
45
+ (contextStr ? `\n\nContext: ${contextStr}` : '')
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Handle tool execution error with detailed logging
51
+ * Logs the error and throws a formatted error with full context
52
+ *
53
+ * @param error - The caught error
54
+ * @param context - Additional context about the operation
55
+ * @throws Error with detailed message including stack trace and context
56
+ */
57
+ export function handleToolError(error: unknown, context: ErrorContext): never {
58
+ const detailedMessage = formatDetailedError(error, context);
59
+ throw new Error(detailedMessage);
60
+ }
61
+
62
+ /**
63
+ * Wrap an async operation with detailed error handling
64
+ *
65
+ * @param operation - The async operation to execute
66
+ * @param context - Error context for logging
67
+ * @returns Result of the operation
68
+ * @throws Error with detailed context if operation fails
69
+ */
70
+ export async function withErrorHandling<T>(
71
+ operation: () => Promise<T>,
72
+ context: ErrorContext
73
+ ): Promise<T> {
74
+ try {
75
+ return await operation();
76
+ } catch (error) {
77
+ handleToolError(error, context);
78
+ }
79
+ }