@@ -144,12 +144,58 @@ describe('StorageClientImpl', () => {
144144 await storageClientImpl . start ( ) ;
145145 expect ( storageClientImpl . getStorage ( ) ) . not . toBeNull ( ) ;
146146
147- await storageClientImpl . stop ( ) ;
147+ await storageClientImpl . stop ( mockRuntime ) ;
148148
149149 expect ( ( ) => storageClientImpl . getStorage ( ) ) . toThrow ( 'Storage client not initialized' ) ;
150150 expect ( ( ) => storageClientImpl . getConfig ( ) ) . toThrow ( 'Storage client not initialized' ) ;
151151 } ) ;
152152
153+ describe ( 'error logging' , ( ) => {
154+ it ( 'should log full error object with stacktrace during client initialization' , async ( ) => {
155+ // Create an error with a stack trace
156+ const errorWithStack = new Error ( 'API connection failed with stack' ) ;
157+
158+ // Mock the client creation to throw our error with stack
159+ const createSpy = vi . spyOn ( Storage , 'create' ) . mockRejectedValueOnce ( errorWithStack ) ;
160+
161+ // Expect the start method to throw
162+ await expect ( storageClientImpl . start ( ) ) . rejects . toThrow ( 'API connection failed with stack' ) ;
163+
164+ // Verify error logging received the full error object
165+ expect ( elizaLogger . error ) . toHaveBeenCalled ( ) ;
166+
167+ // Get the first argument passed to elizaLogger.error
168+ const errorArg = ( elizaLogger . error as any ) . mock . calls [ 0 ] [ 0 ] ;
169+
170+ // Verify it's the full error with stack
171+ expect ( errorArg ) . toBe ( errorWithStack ) ;
172+ expect ( errorArg ) . toBeInstanceOf ( Error ) ;
173+ expect ( errorArg ) . toEqual ( expect . objectContaining ( {
174+ message : 'API connection failed with stack'
175+ } ) ) ;
176+
177+ // Clean up
178+ createSpy . mockRestore ( ) ;
179+ } ) ;
180+
181+ it ( 'should include custom context message with error logs' , async ( ) => {
182+ const errorWithStack = new Error ( 'Client initialization failed' ) ;
183+ const createSpy = vi . spyOn ( Storage , 'create' ) . mockRejectedValueOnce ( errorWithStack ) ;
184+
185+ // Try to start the client, which should fail
186+ await expect ( storageClientImpl . start ( ) ) . rejects . toThrow ( 'Client initialization failed' ) ;
187+
188+ // Check that a context message is provided as the second parameter
189+ expect ( elizaLogger . error ) . toHaveBeenCalledWith (
190+ errorWithStack ,
191+ "❌ Storage client failed to start"
192+ ) ;
193+
194+ // Clean up
195+ createSpy . mockRestore ( ) ;
196+ } ) ;
197+ } ) ;
198+
153199 describe ( 'getContent' , ( ) => {
154200 it ( 'should fetch content from the configured gateway URL' , async ( ) => {
155201 await storageClientImpl . start ( ) ;
@@ -183,6 +229,27 @@ describe('StorageClientImpl', () => {
183229
184230 await expect ( storageClientImpl . getContent ( testCid ) ) . rejects . toThrow ( 'Network error' ) ;
185231 } ) ;
232+
233+ it ( 'should log full error object when fetch fails' , async ( ) => {
234+ await storageClientImpl . start ( ) ;
235+ const testCid = 'bafytest123' ;
236+ const fetchError = new Error ( 'Network fetch error with stack' ) ;
237+ ( global . fetch as any ) . mockRejectedValueOnce ( fetchError ) ;
238+
239+ // The getContent method doesn't have error logging, so this test is confirming
240+ // that it properly propagates the error without losing the stack
241+ await expect ( storageClientImpl . getContent ( testCid ) ) . rejects . toThrow ( 'Network fetch error with stack' ) ;
242+
243+ // Verify the error object is intact with its properties
244+ try {
245+ await storageClientImpl . getContent ( testCid ) ;
246+ } catch ( error ) {
247+ expect ( error ) . toBe ( fetchError ) ;
248+ expect ( error ) . toBeInstanceOf ( Error ) ;
249+ expect ( error ) . toHaveProperty ( 'stack' ) ;
250+ expect ( error . message ) . toBe ( 'Network fetch error with stack' ) ;
251+ }
252+ } ) ;
186253 } ) ;
187254} ) ;
188255
0 commit comments