@@ -323,17 +323,27 @@ if (typeof IS_MINIFIED !== 'undefined') {
323
323
// differ in their name ( either letter difference or difference of case )
324
324
if ( errSym !== symbol . name ) {
325
325
const parsed = p5 . _getErrorStackParser ( ) . parse ( error ) ;
326
- const location =
327
- parsed [ 0 ] && parsed [ 0 ] . fileName
328
- ? `${ parsed [ 0 ] . fileName } :${ parsed [ 0 ] . lineNumber } :${
329
- parsed [ 0 ] . columnNumber
330
- } `
331
- : null ;
326
+ let locationObj ;
327
+ if (
328
+ parsed &&
329
+ parsed [ 0 ] &&
330
+ parsed [ 0 ] . fileName &&
331
+ parsed [ 0 ] . lineNumber &&
332
+ parsed [ 0 ] . columnNumber
333
+ ) {
334
+ locationObj = {
335
+ location : `${ parsed [ 0 ] . fileName } :${ parsed [ 0 ] . lineNumber } :${
336
+ parsed [ 0 ] . columnNumber
337
+ } `,
338
+ file : parsed [ 0 ] . fileName ,
339
+ line : parsed [ 0 ] . lineNumber
340
+ } ;
341
+ }
332
342
const msg = translator ( 'fes.misspelling' , {
333
343
name : errSym ,
334
344
actualName : symbol . name ,
335
345
type : symbol . type ,
336
- location : location ? translator ( 'fes.location' , { location } ) : ''
346
+ location : locationObj ? translator ( 'fes.location' , locationObj ) : ''
337
347
} ) ;
338
348
339
349
if ( log ) {
@@ -379,44 +389,59 @@ if (typeof IS_MINIFIED !== 'undefined') {
379
389
}
380
390
}
381
391
392
+ // in some cases ( errors in promises, callbacks, etc), no entry-point
393
+ // function may be found in the stacktrace. In that case just use the
394
+ // entire stacktrace for friendlyStack
382
395
if ( ! friendlyStack ) friendlyStack = stacktrace ;
383
396
384
397
if ( isInternal ) {
398
+ // the frameIndex property is added before the filter, so frameIndex
399
+ // corresponds to the index of a frame in the original stacktrace.
400
+ // Then we filter out all frames which belong to the file that contains
401
+ // the p5 library
385
402
friendlyStack = friendlyStack
386
403
. map ( ( frame , index ) => {
387
404
frame . frameIndex = index ;
388
405
return frame ;
389
406
} )
390
407
. filter ( frame => frame . fileName !== p5FileName ) ;
391
408
409
+ // get the function just above the topmost frame in the friendlyStack.
410
+ // i.e the name of the library function called from user's code
392
411
const func = stacktrace [ friendlyStack [ 0 ] . frameIndex - 1 ] . functionName
393
412
. split ( '.' )
394
413
. slice ( - 1 ) [ 0 ] ;
395
414
396
- let location ;
415
+ // Try and get the location (line no.) from the top element of the stack
416
+ let locationObj ;
397
417
if (
398
418
friendlyStack [ 0 ] . fileName &&
399
419
friendlyStack [ 0 ] . lineNumber &&
400
420
friendlyStack [ 0 ] . columnNumber
401
421
) {
402
- location = `${ friendlyStack [ 0 ] . fileName } :${
403
- friendlyStack [ 0 ] . lineNumber
404
- } :${ friendlyStack [ 0 ] . columnNumber } `;
422
+ locationObj = {
423
+ location : `${ friendlyStack [ 0 ] . fileName } :${
424
+ friendlyStack [ 0 ] . lineNumber
425
+ } :${ friendlyStack [ 0 ] . columnNumber } `,
426
+ file : friendlyStack [ 0 ] . fileName . split ( '/' ) . slice ( - 1 ) ,
427
+ line : friendlyStack [ 0 ] . lineNumber
428
+ } ;
429
+
430
+ // if already handled by another part of the FES, don't handle again
431
+ if ( p5 . _fesLogCache [ locationObj . location ] ) return [ true , null ] ;
405
432
}
406
433
407
- // If already been handled by another component of the FES
408
- if ( p5 . _fesLogCache [ location ] ) return [ true , null ] ;
434
+ // Check if the error is due to a non loadX method being used incorrectly
435
+ // in preload
409
436
if (
410
437
currentEntryPoint === 'preload' &&
411
438
p5 . prototype . _preloadMethods [ func ] == null
412
439
) {
413
440
p5 . _friendlyError (
414
441
translator ( 'fes.wrongPreload' , {
415
442
func : func ,
416
- location : location
417
- ? translator ( 'fes.location' , {
418
- location
419
- } )
443
+ location : locationObj
444
+ ? translator ( 'fes.location' , locationObj )
420
445
: '' ,
421
446
error : error . message
422
447
} ) ,
@@ -427,7 +452,9 @@ if (typeof IS_MINIFIED !== 'undefined') {
427
452
p5 . _friendlyError (
428
453
translator ( 'fes.libraryError' , {
429
454
func : func ,
430
- location : location ,
455
+ location : locationObj
456
+ ? translator ( 'fes.location' , locationObj )
457
+ : '' ,
431
458
error : error . message
432
459
} ) ,
433
460
func
@@ -437,6 +464,8 @@ if (typeof IS_MINIFIED !== 'undefined') {
437
464
return [ isInternal , friendlyStack ] ;
438
465
} ;
439
466
467
+ // prints a friendly stacktrace which only includes user-written functions
468
+ // and is easier for newcomers to understand
440
469
const printFriendlyStack = friendlyStack => {
441
470
if ( friendlyStack . length > 1 ) {
442
471
let stacktraceMsg = '' ;
@@ -478,7 +507,12 @@ if (typeof IS_MINIFIED !== 'undefined') {
478
507
const log = p5 . _fesLogger ;
479
508
480
509
let stacktrace = p5 . _getErrorStackParser ( ) . parse ( error ) ;
510
+ // process the stacktrace from the browser and simplify it to give
511
+ // friendlyStack.
481
512
let [ isInternal , friendlyStack ] = processStack ( error , stacktrace ) ;
513
+
514
+ // if this is an internal library error, the type of the error is not relevant,
515
+ // only the user code that lead to it is. Show the friendlyStack and return
482
516
if ( isInternal ) {
483
517
if ( friendlyStack ) printFriendlyStack ( friendlyStack ) ;
484
518
return ;
@@ -504,20 +538,28 @@ if (typeof IS_MINIFIED !== 'undefined') {
504
538
505
539
if ( ! matchedError ) return ;
506
540
507
- let location ;
541
+ // Try and get the location from the top element of the stack
542
+ let locationObj ;
508
543
if (
509
544
stacktrace &&
510
545
stacktrace [ 0 ] . fileName &&
511
546
stacktrace [ 0 ] . lineNumber &&
512
547
stacktrace [ 0 ] . columnNumber
513
548
) {
514
- location = `${ stacktrace [ 0 ] . fileName } :${ stacktrace [ 0 ] . lineNumber } :${
515
- stacktrace [ 0 ] . columnNumber
516
- } `;
549
+ locationObj = {
550
+ location : `${ stacktrace [ 0 ] . fileName } :${ stacktrace [ 0 ] . lineNumber } :${
551
+ stacktrace [ 0 ] . columnNumber
552
+ } `,
553
+ file : stacktrace [ 0 ] . fileName . split ( '/' ) . slice ( - 1 ) ,
554
+ line : friendlyStack [ 0 ] . lineNumber
555
+ } ;
517
556
}
518
557
519
558
switch ( error . name ) {
520
559
case 'SyntaxError' : {
560
+ // We can't really do much with syntax errors other than try to use
561
+ // a simpler framing of the error message. The stack isn't available
562
+ // for syntax errors
521
563
switch ( matchedError . type ) {
522
564
case 'INVALIDTOKEN' : {
523
565
let url =
@@ -568,16 +610,13 @@ if (typeof IS_MINIFIED !== 'undefined') {
568
610
url1,
569
611
url2,
570
612
symbol : errSym ,
571
- location : location
572
- ? translator ( 'fes.location' , {
573
- location
574
- } )
613
+ location : locationObj
614
+ ? translator ( 'fes.location' , locationObj )
575
615
: ''
576
616
} )
577
617
) ;
578
618
579
619
if ( friendlyStack ) printFriendlyStack ( friendlyStack ) ;
580
-
581
620
break ;
582
621
}
583
622
}
@@ -589,20 +628,22 @@ if (typeof IS_MINIFIED !== 'undefined') {
589
628
case 'NOTFUNC' : {
590
629
let errSym = matchedError . match [ 1 ] ;
591
630
let splitSym = errSym . split ( '.' ) ;
592
- let location ;
593
631
let url =
594
632
'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_a_function#What_went_wrong' ;
633
+
634
+ // if errSym is aa.bb.cc , symbol would be cc and obj would aa.bb
595
635
let translationObj = {
596
636
url,
597
637
symbol : splitSym [ splitSym . length - 1 ] ,
598
638
obj : splitSym . slice ( 0 , splitSym . length - 1 ) . join ( '.' ) ,
599
- location : location
600
- ? translator ( 'fes.location' , {
601
- location
602
- } )
639
+ location : locationObj
640
+ ? translator ( 'fes.location' , locationObj )
603
641
: ''
604
642
} ;
605
643
644
+ // There are two cases to handle here. When the function is called
645
+ // as a property of an object and when it's called independently.
646
+ // Both have different explanations.
606
647
if ( splitSym . length > 1 ) {
607
648
p5 . _friendlyError (
608
649
translator ( 'fes.globalErrors.type.notfuncObj' , translationObj )
@@ -612,6 +653,9 @@ if (typeof IS_MINIFIED !== 'undefined') {
612
653
translator ( 'fes.globalErrors.type.notfunc' , translationObj )
613
654
) ;
614
655
}
656
+
657
+ if ( friendlyStack ) printFriendlyStack ( friendlyStack ) ;
658
+ break ;
615
659
}
616
660
}
617
661
}
0 commit comments