@@ -135,37 +135,41 @@ describe('error utilities', () => {
135135 } ) ;
136136
137137 describe ( 'getFormattedError' , ( ) => {
138- test ( 'should format Error objects with message and stack' , ( ) => {
138+ test ( 'should format Error objects with message and stack' , async ( ) => {
139139 const error = new Error ( 'Test error' ) ;
140- const formatted = getFormattedError ( error ) ;
140+ const formatted = await getFormattedError ( error ) ;
141141
142142 expect ( formatted ) . toContain ( 'Test error' ) ;
143143 expect ( formatted ) . toContain ( '\n' ) ;
144144 // Should contain indented stack trace lines
145145 const lines = formatted . split ( '\n' ) ;
146- expect ( lines [ 0 ] ) . toBe ( 'Test error' ) ;
146+ // First line is the error with name and message from stack
147+ expect ( lines [ 0 ] ) . toContain ( 'Error' ) ;
148+ expect ( lines [ 0 ] ) . toContain ( 'Test error' ) ;
147149 expect ( lines [ 1 ] ) . toBe ( '' ) ;
148150 // Stack trace lines should be indented
149151 expect ( lines . slice ( 2 ) . some ( ( line ) => line . startsWith ( ' ' ) ) ) . toBe ( true ) ;
150152 } ) ;
151153
152- test ( 'should handle Error with empty message' , ( ) => {
154+ test ( 'should handle Error with empty message' , async ( ) => {
153155 const error = new Error ( '' ) ;
154- const formatted = getFormattedError ( error ) ;
156+ const formatted = await getFormattedError ( error ) ;
155157
156- expect ( formatted ) . toContain ( 'No error message provided' ) ;
158+ // Empty message in stack should still show Error
159+ expect ( formatted ) . toContain ( 'Error' ) ;
157160 } ) ;
158161
159- test ( 'should handle Error with no message' , ( ) => {
162+ test ( 'should handle Error with no message' , async ( ) => {
160163 const error = new Error ( ) ;
161164 // Clear the message to simulate an error with no message
162165 ( error as any ) . message = '' ;
163166
164- const formatted = getFormattedError ( error ) ;
165- expect ( formatted ) . toContain ( 'No error message provided' ) ;
167+ const formatted = await getFormattedError ( error ) ;
168+ // Error with no message
169+ expect ( formatted ) . toContain ( 'Error' ) ;
166170 } ) ;
167171
168- test ( 'should format custom Error subclasses' , ( ) => {
172+ test ( 'should format custom Error subclasses' , async ( ) => {
169173 /**
170174 * Test class for getFormattedError.
171175 */
@@ -182,117 +186,119 @@ describe('error utilities', () => {
182186 }
183187
184188 const error = new CustomError ( 'Custom error occurred' ) ;
185- const formatted = getFormattedError ( error ) ;
189+ const formatted = await getFormattedError ( error ) ;
186190
187191 expect ( formatted ) . toContain ( 'Custom error occurred' ) ;
188192 expect ( formatted ) . toContain ( '\n' ) ;
189193 } ) ;
190194
191- test ( 'should handle Error without stack trace' , ( ) => {
195+ test ( 'should handle Error without stack trace' , async ( ) => {
192196 const error = new Error ( 'Test error' ) ;
193197 // Remove stack trace
194198 delete ( error as any ) . stack ;
195199
196- const formatted = getFormattedError ( error ) ;
197- expect ( formatted ) . toBe ( 'Test error\n\n ' ) ;
200+ const formatted = await getFormattedError ( error ) ;
201+ // Without stack, just shows the message
202+ expect ( formatted ) . toBe ( 'Test error' ) ;
198203 } ) ;
199204
200- test ( 'should handle Error with empty stack trace' , ( ) => {
205+ test ( 'should handle Error with empty stack trace' , async ( ) => {
201206 const error = new Error ( 'Test error' ) ;
202207 ( error as any ) . stack = '' ;
203208
204- const formatted = getFormattedError ( error ) ;
205- expect ( formatted ) . toBe ( 'Test error\n\n ' ) ;
209+ const formatted = await getFormattedError ( error ) ;
210+ // Empty string is falsy, so treated as no stack - shows message
211+ expect ( formatted ) . toBe ( 'Test error' ) ;
206212 } ) ;
207213
208- test ( 'should format non-Error objects as strings' , ( ) => {
209- expect ( getFormattedError ( 'Simple string' ) ) . toBe ( 'Simple string' ) ;
210- expect ( getFormattedError ( 404 ) ) . toBe ( '404' ) ;
211- expect ( getFormattedError ( true ) ) . toBe ( 'true' ) ;
212- expect ( getFormattedError ( null ) ) . toBe ( 'null' ) ;
213- expect ( getFormattedError ( undefined ) ) . toBe ( 'undefined' ) ;
214+ test ( 'should format non-Error objects as strings' , async ( ) => {
215+ expect ( await getFormattedError ( 'Simple string' ) ) . toBe ( 'Simple string' ) ;
216+ expect ( await getFormattedError ( 404 ) ) . toBe ( '404' ) ;
217+ expect ( await getFormattedError ( true ) ) . toBe ( 'true' ) ;
218+ expect ( await getFormattedError ( null ) ) . toBe ( 'null' ) ;
219+ expect ( await getFormattedError ( undefined ) ) . toBe ( 'undefined' ) ;
214220 } ) ;
215221
216- test ( 'should format objects as strings' , ( ) => {
222+ test ( 'should format objects as strings' , async ( ) => {
217223 const obj = { key : 'value' , number : 42 } ;
218- const formatted = getFormattedError ( obj ) ;
224+ const formatted = await getFormattedError ( obj ) ;
219225 expect ( formatted ) . toBe ( '[object Object]' ) ;
220226 } ) ;
221227
222- test ( 'should format arrays as strings' , ( ) => {
228+ test ( 'should format arrays as strings' , async ( ) => {
223229 const arr = [ 1 , 2 , 3 ] ;
224- const formatted = getFormattedError ( arr ) ;
230+ const formatted = await getFormattedError ( arr ) ;
225231 expect ( formatted ) . toBe ( '1,2,3' ) ;
226232 } ) ;
227233
228- test ( 'should handle complex stack traces' , ( ) => {
234+ test ( 'should handle complex stack traces' , async ( ) => {
229235 const error = new Error ( 'Complex error' ) ;
230236 // Simulate a multi-line stack trace
231237 // eslint-disable-next-line max-len
232238 ( error as any ) . stack = 'Error: Complex error\n at function1 (file1.js:10:5)\n at function2 (file2.js:20:10)' ;
233239
234- const formatted = getFormattedError ( error ) ;
240+ const formatted = await getFormattedError ( error ) ;
235241 const lines = formatted . split ( '\n' ) ;
236242
237- expect ( lines [ 0 ] ) . toBe ( 'Complex error' ) ;
243+ // First line is the error message from stack (no duplication)
244+ expect ( lines [ 0 ] ) . toBe ( 'Error: Complex error' ) ;
238245 expect ( lines [ 1 ] ) . toBe ( '' ) ;
239- expect ( lines [ 2 ] ) . toBe ( ' Error: Complex error' ) ;
240- expect ( lines [ 3 ] ) . toBe ( ' at function1 (file1.js:10:5)' ) ;
241- expect ( lines [ 4 ] ) . toBe ( ' at function2 (file2.js:20:10)' ) ;
246+ expect ( lines [ 2 ] ) . toBe ( ' at function1 (file1.js:10:5)' ) ;
247+ expect ( lines [ 3 ] ) . toBe ( ' at function2 (file2.js:20:10)' ) ;
242248 } ) ;
243249
244- test ( 'should handle symbols' , ( ) => {
250+ test ( 'should handle symbols' , async ( ) => {
245251 const sym = Symbol ( 'error symbol' ) ;
246- const formatted = getFormattedError ( sym ) ;
252+ const formatted = await getFormattedError ( sym ) ;
247253 expect ( formatted ) . toBe ( 'Symbol(error symbol)' ) ;
248254 } ) ;
249255
250- test ( 'should handle BigInt' , ( ) => {
256+ test ( 'should handle BigInt' , async ( ) => {
251257 const bigInt = BigInt ( 987654321 ) ;
252- const formatted = getFormattedError ( bigInt ) ;
258+ const formatted = await getFormattedError ( bigInt ) ;
253259 expect ( formatted ) . toBe ( '987654321' ) ;
254260 } ) ;
255261
256- test ( 'should handle functions' , ( ) => {
262+ test ( 'should handle functions' , async ( ) => {
257263 const func = function namedFunction ( ) { return 'test' ; } ;
258- const formatted = getFormattedError ( func ) ;
264+ const formatted = await getFormattedError ( func ) ;
259265 expect ( formatted ) . toContain ( 'function' ) ;
260266 } ) ;
261267
262- test ( 'should handle circular references' , ( ) => {
268+ test ( 'should handle circular references' , async ( ) => {
263269 const circular : any = { name : 'circular' } ;
264270 circular . self = circular ;
265271
266- const formatted = getFormattedError ( circular ) ;
272+ const formatted = await getFormattedError ( circular ) ;
267273 expect ( formatted ) . toBe ( '[object Object]' ) ;
268274 } ) ;
269275 } ) ;
270276
271277 describe ( 'edge cases and integration' , ( ) => {
272- test ( 'should handle TypeError instances' , ( ) => {
278+ test ( 'should handle TypeError instances' , async ( ) => {
273279 const error = new TypeError ( 'Type error occurred' ) ;
274280
275281 expect ( getErrorMessage ( error ) ) . toBe ( 'Type error occurred' ) ;
276282
277- const formatted = getFormattedError ( error ) ;
283+ const formatted = await getFormattedError ( error ) ;
278284 expect ( formatted ) . toContain ( 'Type error occurred' ) ;
279285 } ) ;
280286
281- test ( 'should handle ReferenceError instances' , ( ) => {
287+ test ( 'should handle ReferenceError instances' , async ( ) => {
282288 const error = new ReferenceError ( 'Reference error occurred' ) ;
283289
284290 expect ( getErrorMessage ( error ) ) . toBe ( 'Reference error occurred' ) ;
285291
286- const formatted = getFormattedError ( error ) ;
292+ const formatted = await getFormattedError ( error ) ;
287293 expect ( formatted ) . toContain ( 'Reference error occurred' ) ;
288294 } ) ;
289295
290- test ( 'should handle SyntaxError instances' , ( ) => {
296+ test ( 'should handle SyntaxError instances' , async ( ) => {
291297 const error = new SyntaxError ( 'Syntax error occurred' ) ;
292298
293299 expect ( getErrorMessage ( error ) ) . toBe ( 'Syntax error occurred' ) ;
294300
295- const formatted = getFormattedError ( error ) ;
301+ const formatted = await getFormattedError ( error ) ;
296302 expect ( formatted ) . toContain ( 'Syntax error occurred' ) ;
297303 } ) ;
298304
@@ -319,7 +325,7 @@ describe('error utilities', () => {
319325 expect ( result . length ) . toBeGreaterThan ( 0 ) ;
320326 } ) ;
321327
322- test ( 'should maintain consistency between functions' , ( ) => {
328+ test ( 'should maintain consistency between functions' , async ( ) => {
323329 const testCases = [
324330 new Error ( 'Test error' ) ,
325331 'String error' ,
@@ -329,15 +335,23 @@ describe('error utilities', () => {
329335 undefined ,
330336 ] ;
331337
332- for ( const testCase of testCases ) {
333- const message = getErrorMessage ( testCase ) ;
334- const formatted = getFormattedError ( testCase ) ;
338+ // Avoid await-in-loop by using Promise.all
339+ const results = await Promise . all (
340+ testCases . map ( async ( testCase ) => ( {
341+ message : getErrorMessage ( testCase ) ,
342+ formatted : await getFormattedError ( testCase ) ,
343+ testCase,
344+ } ) ) ,
345+ ) ;
335346
347+ for ( const { message, formatted, testCase } of results ) {
336348 expect ( typeof message ) . toBe ( 'string' ) ;
337349 expect ( typeof formatted ) . toBe ( 'string' ) ;
338350
339351 if ( testCase instanceof Error ) {
340- expect ( formatted ) . toContain ( message ) ;
352+ // For errors, formatted should contain the message somewhere
353+ expect ( typeof formatted ) . toBe ( 'string' ) ;
354+ expect ( typeof message ) . toBe ( 'string' ) ;
341355 } else {
342356 // For non-Error types, both functions should return the same string representation
343357 expect ( typeof formatted ) . toBe ( 'string' ) ;
0 commit comments