Skip to content

Commit 5d4fd14

Browse files
A M Chungaaronccasanovaoutofambit
authored
New FES Contributor Docs + FES Survey Link (#5460)
* inline doc organization * new links * fix: Update the rem instance method to be chainable * chore: Adjust formatting * fes ref + dev doc + inline doc updates * edited for clarity * updated reflecting comments from kate Co-authored-by: Aaron Casanova <[email protected]> Co-authored-by: Aaron Casanova <[email protected]> Co-authored-by: evelyn masso <[email protected]>
1 parent 810ba08 commit 5d4fd14

File tree

9 files changed

+810
-390
lines changed

9 files changed

+810
-390
lines changed

contributor_docs/fes_reference_dev_notes.md

Lines changed: 485 additions & 0 deletions
Large diffs are not rendered by default.

contributor_docs/friendly_error_system.md

Lines changed: 102 additions & 220 deletions
Large diffs are not rendered by default.

src/core/friendly_errors/browser_errors.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
// Different browsers may use different error strings for the same error.
2-
// Extracting info from them is much easier and cleaner if we have a predefined
3-
// lookup against which we try and match the errors obtained from the browser,
4-
// classify them into types and extract the required information. The contents
5-
// of this file serve as that lookup. The FES can use this to give a simplified
6-
// explanation for all kinds of errors.
1+
// This contains a data table used by ./fes_core.js/fesErrorMonitor().
2+
//
3+
// Note: Different browsers use different error strings for the same error.
4+
// Extracting info from the browser error messages is easier and cleaner
5+
// if we have a predefined lookup. This file serves as that lookup.
6+
// Using this lookup we match the errors obtained from the browser, classify
7+
// them into types and extract the required information.
8+
// The FES can use the extracted info to generate a friendly error message
9+
// for the matching error.
710
const strings = {
811
ReferenceError: [
912
{

src/core/friendly_errors/fes_core.js

Lines changed: 97 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,25 @@
22
* @for p5
33
* @requires core
44
*
5-
* This is the main file for the Friendly Error System (FES). Here is a
5+
* This is the main file for the Friendly Error System (FES), containing
6+
* the core as well as miscellaneous functionality of the FES. Here is a
67
* brief outline of the functions called in this system.
78
*
8-
* The FES may be invoked by a call to either (1) _validateParameters,
9-
* (2) _friendlyFileLoadError, (3) _friendlyError, (4) helpForMisusedAtTopLevelCode,
10-
* or (5) _fesErrorMontitor.
9+
* The FES may be invoked by a call to either
10+
* (1) _validateParameters, (2) _friendlyFileLoadError, (3) _friendlyError,
11+
* (4) helpForMisusedAtTopLevelCode, or (5) _fesErrorMontitor.
1112
*
12-
* _validateParameters is located in validate_params.js along with other code used
13-
* for parameter validation.
14-
* _friendlyFileLoadError is located in file_errors.js along with other code used for
15-
* dealing with file load errors.
16-
* Apart from this, there's also a file stacktrace.js, which contains the code to parse
17-
* the error stack, borrowed from https://github.com/stacktracejs/stacktrace.js
13+
* _validateParameters is located in validate_params.js along with other code
14+
* used for parameter validation.
15+
* _friendlyFileLoadError is located in file_errors.js along with other code
16+
* used for dealing with file load errors.
17+
* Apart from this, there's also a file stacktrace.js, which contains the code
18+
* to parse the error stack, borrowed from:
19+
* https://github.com/stacktracejs/stacktrace.js
1820
*
19-
* This file contains the core as well as miscellaneous functionality of the FES.
20-
*
21-
* helpForMisusedAtTopLevelCode is called by this file on window load to check for use
22-
* of p5.js functions outside of setup() or draw()
23-
* Items 1-3 above are called by functions in the p5 library located in other files.
24-
*
25-
* _fesErrorMonitor can be called either by an error event, an unhandled rejection event
26-
* or it can be manually called in a catch block as follows:
27-
* try { someCode(); } catch(err) { p5._fesErrorMonitor(err); }
28-
* fesErrorMonitor is responsible for handling all kinds of errors that the browser may show.
29-
* It gives a simplified explanation for these. It currently works with some kinds of
30-
* ReferenceError, SyntaxError, and TypeError. The complete list of supported errors can be
31-
* found in browser_errors.js.
32-
*
33-
* _friendlyFileLoadError is called by the loadX() methods.
34-
* _friendlyError can be called by any function to offer a helpful error message.
35-
*
36-
* _validateParameters is called by functions in the p5.js API to help users ensure
37-
* ther are calling p5 function with the right parameter types. The property
38-
* disableFriendlyErrors = false can be set from a p5.js sketch to turn off parameter
39-
* checking. The call sequence from _validateParameters looks something like this:
40-
*
41-
* _validateParameters
42-
* buildArgTypeCache
43-
* addType
44-
* lookupParamDoc
45-
* scoreOverload
46-
* testParamTypes
47-
* testParamType
48-
* getOverloadErrors
49-
* _friendlyParamError
50-
* ValidationError
51-
* report
52-
* friendlyWelcome
53-
*
54-
* The call sequences to _friendlyFileLoadError and _friendlyError are like this:
55-
* _friendlyFileLoadError
56-
* report
57-
*
58-
* _friendlyError
59-
* report
60-
*
61-
* The call sequence for _fesErrorMonitor roughly looks something like:
62-
* _fesErrorMonitor
63-
* processStack
64-
* printFriendlyError
65-
* (if type of error is ReferenceError)
66-
* _handleMisspelling
67-
* computeEditDistance
68-
* report
69-
* report
70-
* printFriendlyStack
71-
* (if type of error is SyntaxError, TypeError, etc)
72-
* report
73-
* printFriendlyStack
74-
*
75-
* report() is the main function that prints directly to console with the output
76-
* of the error helper message. Note: friendlyWelcome() also prints to console directly.
21+
* For more detailed information on the FES functions, including the call
22+
* sequence of each function, please look at the FES Reference + Dev Notes:
23+
* https://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md
7724
*/
7825
import p5 from '../main';
7926
import { translator } from '../internationalization';
@@ -176,8 +123,8 @@ if (typeof IS_MINIFIED !== 'undefined') {
176123
*
177124
* @method mapToReference
178125
* @private
179-
* @param {String} message the words to be said
180-
* @param {String} [func] the name of the function to link
126+
* @param {String} message the words to be said
127+
* @param {String} [func] the name of function
181128
*
182129
* @returns {String}
183130
*/
@@ -199,12 +146,13 @@ if (typeof IS_MINIFIED !== 'undefined') {
199146

200147
/**
201148
* Prints out a fancy, colorful message to the console log
149+
* Attaches Friendly Errors prefix [fes.pre] to the message.
202150
*
203151
* @method _report
204152
* @private
205-
* @param {String} message the words to be said
206-
* @param {String} [func] the name of the function to link
207-
* @param {Number|String} [color] CSS color string or error type
153+
* @param {String} message Message to be printed
154+
* @param {String} [func] Name of function
155+
* @param {Number|String} [color] CSS color code
208156
*
209157
* @return console logs
210158
*/
@@ -242,16 +190,17 @@ if (typeof IS_MINIFIED !== 'undefined') {
242190
*
243191
* @method _friendlyError
244192
* @private
245-
* @param {Number} message message to be printed
246-
* @param {String} [method] name of method
247-
* @param {Number|String} [color] CSS color string or error type
193+
* @param {String} message Message to be printed
194+
* @param {String} [func] Name of the function linked to error
195+
* @param {Number|String} [color] CSS color code
248196
*/
249-
p5._friendlyError = function(message, method, color) {
250-
p5._report(message, method, color);
197+
p5._friendlyError = function(message, func, color) {
198+
p5._report(message, func, color);
251199
};
252200

253201
/**
254-
* This is called internally if there is a error with autoplay.
202+
* This is called internally if there is an error with autoplay. Generates
203+
* and prints a friendly error message [fes.autoplay].
255204
*
256205
* @method _friendlyAutoplayError
257206
* @private
@@ -265,11 +214,13 @@ if (typeof IS_MINIFIED !== 'undefined') {
265214
};
266215

267216
/**
268-
* An implementation of
269-
* https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm to
270-
* compute the Levenshtein distance. It gives a measure of how dissimilar
271-
* two strings are. If the "distance" between them is small enough, it is
217+
* Measures dissimilarity between two strings by calculating
218+
* the Levenshtein distance.
219+
*
220+
* If the "distance" between them is small enough, it is
272221
* reasonable to think that one is the misspelled version of the other.
222+
*
223+
* Specifically, this uses the Wagner–Fischer algorithm.
273224
* @method computeEditDistance
274225
* @private
275226
* @param {String} w1 the first word
@@ -316,12 +267,15 @@ if (typeof IS_MINIFIED !== 'undefined') {
316267
};
317268

318269
/**
319-
* checks if the various functions such as setup, draw, preload have been
320-
* defined with capitalization mistakes
270+
* Checks capitalization for user defined functions.
271+
*
272+
* Generates and prints a friendly error message using key:
273+
* "fes.checkUserDefinedFns".
274+
*
321275
* @method checkForUserDefinedFunctions
322276
* @private
323-
* @param {*} context The current default context. It's set to window in
324-
* "global mode" and to a p5 instance in "instance mode"
277+
* @param {*} context Current default context. Set to window in
278+
* "global mode" and to a p5 instance in "instance mode"
325279
*/
326280
const checkForUserDefinedFunctions = context => {
327281
if (p5.disableFriendlyErrors) return;
@@ -360,19 +314,17 @@ if (typeof IS_MINIFIED !== 'undefined') {
360314
};
361315

362316
/**
363-
* compares the the symbol caught in the ReferenceErrror to everything
364-
* in misusedAtTopLevel ( all public p5 properties ). The use of
365-
* misusedAtTopLevel here is for convenience as it was an array that was
366-
* already defined when spelling check was implemented. For this particular
367-
* use-case, it's a misnomer.
317+
* Compares the symbol caught in the ReferenceErrror to everything in
318+
* misusedAtTopLevel ( all public p5 properties ).
319+
*
320+
* Generates and prints a friendly error message using key: "fes.misspelling".
368321
*
369322
* @method handleMisspelling
370323
* @private
371-
* @param {String} errSym the symbol to whose spelling to check
372-
* @param {Error} error the ReferenceError object
324+
* @param {String} errSym Symbol to whose spelling to check
325+
* @param {Error} error ReferenceError object
373326
*
374-
* @returns {Boolean} a boolean value indicating if this error was likely due
375-
* to a mis-spelling
327+
* @returns {Boolean} tell whether error was likely due to typo
376328
*/
377329
const handleMisspelling = (errSym, error) => {
378330
if (!misusedAtTopLevelCode) {
@@ -422,7 +374,7 @@ if (typeof IS_MINIFIED !== 'undefined') {
422374
if (matchedSymbols.length === 1) {
423375
// To be used when there is only one closest match. The count parameter
424376
// allows i18n to pick between the keys "fes.misspelling" and
425-
// "fes.misspelling__plural"
377+
// "fes.misspelling_plural"
426378
msg = translator('fes.misspelling', {
427379
name: errSym,
428380
actualName: matchedSymbols[0].name,
@@ -464,8 +416,11 @@ if (typeof IS_MINIFIED !== 'undefined') {
464416
};
465417

466418
/**
467-
* prints a friendly stacktrace which only includes user-written functions
468-
* and is easier for newcomers to understand
419+
* Prints a friendly stacktrace for user-written functions for "global" errors
420+
*
421+
* Generates and prints a friendly error message using key:
422+
* "fes.globalErrors.stackTop", "fes.globalErrors.stackSubseq".
423+
*
469424
* @method printFriendlyStack
470425
* @private
471426
* @param {Array} friendlyStack
@@ -501,21 +456,28 @@ if (typeof IS_MINIFIED !== 'undefined') {
501456

502457
/**
503458
* Takes a stacktrace array and filters out all frames that show internal p5
504-
* details. It also uses this processed stack to figure out if the error
505-
* error happened internally within the library, and if the error was due to
506-
* a non-loadX() method being used in preload
507-
* "Internally" here means that the error exact location of the error (the
508-
* top of the stack) is a piece of code write in the p5.js library (which may
509-
* or may not have been called from the user's sketch)
459+
* details.
460+
*
461+
* Generates and prints a friendly error message using key:
462+
* "fes.wrongPreload", "fes.libraryError".
463+
*
464+
* The processed stack is used to find whether the error happended internally
465+
* within the library, and if the error was due to a non-loadX() method
466+
* being used in preload.
467+
*
468+
* "Internally" here means that the exact location of the error (the top of
469+
* the stack) is a piece of code write in the p5.js library (which may or
470+
* may not have been called from the user's sketch).
510471
*
511472
* @method processStack
512473
* @private
513474
* @param {Error} error
514475
* @param {Array} stacktrace
515476
*
516477
* @returns {Array} An array with two elements, [isInternal, friendlyStack]
517-
* isInternal: a boolean indicating if the error happened internally
518-
* friendlyStack: the simplified stacktrace, with internal details filtered
478+
* isInternal: a boolean value indicating whether the error
479+
* happened internally
480+
* friendlyStack: the filtered (simplified) stacktrace
519481
*/
520482
const processStack = (error, stacktrace) => {
521483
// cannot process a stacktrace that doesn't exist
@@ -635,13 +597,17 @@ if (typeof IS_MINIFIED !== 'undefined') {
635597
};
636598

637599
/**
638-
* The main function for handling global errors. Called when an error
639-
* happens and is responsible for detecting the type of error that
640-
* has happened and showing the appropriate message
600+
* Handles "global" errors that the browser catches.
601+
*
602+
* Called when an error event happens and detects the type of error.
603+
*
604+
* Generates and prints a friendly error message using key:
605+
* "fes.globalErrors.syntax.[*]", "fes.globalErrors.reference.[*]",
606+
* "fes.globalErrors.type.[*]".
641607
*
642608
* @method fesErrorMonitor
643609
* @private
644-
* @param {*} e The object to extract error details from
610+
* @param {*} e Event object to extract error details from
645611
*/
646612
const fesErrorMonitor = e => {
647613
if (p5.disableFriendlyErrors) return;
@@ -986,6 +952,12 @@ misusedAtTopLevelCode = null;
986952
const FAQ_URL =
987953
'https://github.com/processing/p5.js/wiki/p5.js-overview#why-cant-i-assign-variables-using-p5-functions-and-variables-before-setup';
988954

955+
/**
956+
* A helper function for populating misusedAtTopLevel list.
957+
*
958+
* @method defineMisusedAtTopLevelCode
959+
* @private
960+
*/
989961
defineMisusedAtTopLevelCode = () => {
990962
const uniqueNamesFound = {};
991963

@@ -1031,6 +1003,20 @@ defineMisusedAtTopLevelCode = () => {
10311003
misusedAtTopLevelCode.sort((a, b) => b.name.length - a.name.length);
10321004
};
10331005

1006+
/**
1007+
* Detects browser level error event for p5 constants/functions used outside
1008+
* of setup() and draw().
1009+
*
1010+
* Generates and prints a friendly error message using key:
1011+
* "fes.misusedTopLevel".
1012+
*
1013+
* @method helpForMisusedAtTopLevelCode
1014+
* @private
1015+
* @param {Event} e Error event
1016+
* @param {Boolean} log false
1017+
*
1018+
* @returns {Boolean} true
1019+
*/
10341020
const helpForMisusedAtTopLevelCode = (e, log) => {
10351021
if (!log) {
10361022
log = console.log.bind(console);

src/core/friendly_errors/file_errors.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
/**
22
* @for p5
33
* @requires core
4-
*
5-
* This file contains the part of the FES responsible for dealing with
6-
* file load errors
74
*/
85
import p5 from '../main';
96
import { translator } from '../internationalization';
@@ -79,14 +76,16 @@ if (typeof IS_MINIFIED !== 'undefined') {
7976
};
8077
}
8178
};
82-
8379
/**
84-
* This is called internally if there is a error during file loading.
80+
* Called internally if there is an error during file loading.
81+
*
82+
* Generates and prints a friendly error message using key:
83+
* "fes.fileLoadError.[*]".
8584
*
8685
* @method _friendlyFileLoadError
8786
* @private
88-
* @param {Number} errorType
89-
* @param {String} filePath
87+
* @param {Number} errorType Number of file load error type
88+
* @param {String} filePath Path to file caused the error
9089
*/
9190
p5._friendlyFileLoadError = function(errorType, filePath) {
9291
const { message, method } = fileLoadErrorCases(errorType, filePath);

0 commit comments

Comments
 (0)