Skip to content

Commit 71210f5

Browse files
committed
Different text for location + Add inline comments
1 parent 1bafba8 commit 71210f5

File tree

3 files changed

+98
-38
lines changed

3 files changed

+98
-38
lines changed

src/core/friendly_errors/fes_core.js

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -323,17 +323,27 @@ if (typeof IS_MINIFIED !== 'undefined') {
323323
// differ in their name ( either letter difference or difference of case )
324324
if (errSym !== symbol.name) {
325325
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+
}
332342
const msg = translator('fes.misspelling', {
333343
name: errSym,
334344
actualName: symbol.name,
335345
type: symbol.type,
336-
location: location ? translator('fes.location', { location }) : ''
346+
location: locationObj ? translator('fes.location', locationObj) : ''
337347
});
338348

339349
if (log) {
@@ -379,44 +389,59 @@ if (typeof IS_MINIFIED !== 'undefined') {
379389
}
380390
}
381391

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
382395
if (!friendlyStack) friendlyStack = stacktrace;
383396

384397
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
385402
friendlyStack = friendlyStack
386403
.map((frame, index) => {
387404
frame.frameIndex = index;
388405
return frame;
389406
})
390407
.filter(frame => frame.fileName !== p5FileName);
391408

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
392411
const func = stacktrace[friendlyStack[0].frameIndex - 1].functionName
393412
.split('.')
394413
.slice(-1)[0];
395414

396-
let location;
415+
// Try and get the location (line no.) from the top element of the stack
416+
let locationObj;
397417
if (
398418
friendlyStack[0].fileName &&
399419
friendlyStack[0].lineNumber &&
400420
friendlyStack[0].columnNumber
401421
) {
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];
405432
}
406433

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
409436
if (
410437
currentEntryPoint === 'preload' &&
411438
p5.prototype._preloadMethods[func] == null
412439
) {
413440
p5._friendlyError(
414441
translator('fes.wrongPreload', {
415442
func: func,
416-
location: location
417-
? translator('fes.location', {
418-
location
419-
})
443+
location: locationObj
444+
? translator('fes.location', locationObj)
420445
: '',
421446
error: error.message
422447
}),
@@ -427,7 +452,9 @@ if (typeof IS_MINIFIED !== 'undefined') {
427452
p5._friendlyError(
428453
translator('fes.libraryError', {
429454
func: func,
430-
location: location,
455+
location: locationObj
456+
? translator('fes.location', locationObj)
457+
: '',
431458
error: error.message
432459
}),
433460
func
@@ -437,6 +464,8 @@ if (typeof IS_MINIFIED !== 'undefined') {
437464
return [isInternal, friendlyStack];
438465
};
439466

467+
// prints a friendly stacktrace which only includes user-written functions
468+
// and is easier for newcomers to understand
440469
const printFriendlyStack = friendlyStack => {
441470
if (friendlyStack.length > 1) {
442471
let stacktraceMsg = '';
@@ -478,7 +507,12 @@ if (typeof IS_MINIFIED !== 'undefined') {
478507
const log = p5._fesLogger;
479508

480509
let stacktrace = p5._getErrorStackParser().parse(error);
510+
// process the stacktrace from the browser and simplify it to give
511+
// friendlyStack.
481512
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
482516
if (isInternal) {
483517
if (friendlyStack) printFriendlyStack(friendlyStack);
484518
return;
@@ -504,20 +538,28 @@ if (typeof IS_MINIFIED !== 'undefined') {
504538

505539
if (!matchedError) return;
506540

507-
let location;
541+
// Try and get the location from the top element of the stack
542+
let locationObj;
508543
if (
509544
stacktrace &&
510545
stacktrace[0].fileName &&
511546
stacktrace[0].lineNumber &&
512547
stacktrace[0].columnNumber
513548
) {
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+
};
517556
}
518557

519558
switch (error.name) {
520559
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
521563
switch (matchedError.type) {
522564
case 'INVALIDTOKEN': {
523565
let url =
@@ -568,16 +610,13 @@ if (typeof IS_MINIFIED !== 'undefined') {
568610
url1,
569611
url2,
570612
symbol: errSym,
571-
location: location
572-
? translator('fes.location', {
573-
location
574-
})
613+
location: locationObj
614+
? translator('fes.location', locationObj)
575615
: ''
576616
})
577617
);
578618

579619
if (friendlyStack) printFriendlyStack(friendlyStack);
580-
581620
break;
582621
}
583622
}
@@ -589,20 +628,22 @@ if (typeof IS_MINIFIED !== 'undefined') {
589628
case 'NOTFUNC': {
590629
let errSym = matchedError.match[1];
591630
let splitSym = errSym.split('.');
592-
let location;
593631
let url =
594632
'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
595635
let translationObj = {
596636
url,
597637
symbol: splitSym[splitSym.length - 1],
598638
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)
603641
: ''
604642
};
605643

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.
606647
if (splitSym.length > 1) {
607648
p5._friendlyError(
608649
translator('fes.globalErrors.type.notfuncObj', translationObj)
@@ -612,6 +653,9 @@ if (typeof IS_MINIFIED !== 'undefined') {
612653
translator('fes.globalErrors.type.notfunc', translationObj)
613654
);
614655
}
656+
657+
if (friendlyStack) printFriendlyStack(friendlyStack);
658+
break;
615659
}
616660
}
617661
}

src/core/friendly_errors/validate_params.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,27 @@ if (typeof IS_MINIFIED !== 'undefined') {
568568
if (p5._throwValidationErrors) {
569569
throw new p5.ValidationError(message, func, errorObj.type);
570570
}
571-
const location = `${parsed[3].fileName}:${parsed[3].lineNumber}:${
571+
572+
// try to extract the location from where the function was called
573+
if (
574+
parsed[3] &&
575+
parsed[3].fileName &&
576+
parsed[3].lineNumber &&
572577
parsed[3].columnNumber
573-
}`;
574-
if (location) {
575-
translationObj.location = translator('fes.location', { location });
578+
) {
579+
let location = `${parsed[3].fileName}:${parsed[3].lineNumber}:${
580+
parsed[3].columnNumber
581+
}`;
582+
583+
translationObj.location = translator('fes.location', {
584+
location: location,
585+
// for e.g. get "sketch.js" from "https://example.com/abc/sketch.js"
586+
file: parsed[3].fileName.split('/').slice(-1),
587+
line: parsed[3].lineNumber
588+
});
589+
590+
// tell fesErrorMonitor that we have already given a friendly message
591+
// for this line, so it need not to do the same in case of an error
576592
p5._fesLogCache[location] = true;
577593
}
578594
} catch (err) {

translations/en/translation.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
}
3737
},
3838
"libraryError": "An error with message \"{{error}}\" occured inside the p5js library when you called {{func}} {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.",
39-
"location": "(at {{location}})",
39+
"location": "(on line {{line}} in {{file}} [{{location}}])",
4040
"misspelling": "It seems that you may have accidently written {{name}} instead of {{actualName}} {{location}}.\n\nPlease correct it to {{actualName}} if you wish to use the {{type}} from p5.js",
4141
"misusedTopLevel": "Did you just try to use p5.js's {{symbolName}} {{symbolType}}? If so, you may want to move it into your sketch's setup() function.\n\nFor more details, see: {{link}}",
4242
"positions": {
@@ -53,7 +53,7 @@
5353
"p_8": "eighth",
5454
"p_9": "ninth"
5555
},
56-
"pre": "🌸 p5.js says: {{message}}",
56+
"pre": "\n🌸 p5.js says: {{message}}",
5757
"welcome": "Welcome! This is your friendly debugger. To turn me off, switch to using p5.min.js.",
5858
"wrongPreload": "An error with message \"{{error}}\" occured inside the p5js library when you called {{func}} {{location}}.\n\nIf not stated otherwise, it might be due to {{func}} being called from preload. Nothing besides load calls (loadImage, loadJSON, loadFont, loadStrings, etc.) should be inside the preload function."
5959
}

0 commit comments

Comments
 (0)