From cd29f0368b2398c4680e8160315f291dacfc00b2 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Fri, 21 May 2021 17:37:35 +0530 Subject: [PATCH 01/18] initial changes --- lib/empty-example/sketch.js | 9 ++- src/core/friendly_errors/browser_errors.js | 35 ++++++++ src/core/friendly_errors/fes_core.js | 92 ++++++++++++++++++++++ translations/en/translation.json | 8 +- translations/es/translation.json | 15 +++- 5 files changed, 154 insertions(+), 5 deletions(-) diff --git a/lib/empty-example/sketch.js b/lib/empty-example/sketch.js index de6c862644..5737f34b08 100644 --- a/lib/empty-example/sketch.js +++ b/lib/empty-example/sketch.js @@ -1,7 +1,14 @@ +console.log(a); +const a=100; + function setup() { // put setup code here -} + createCanvas(400, 400); + +} function draw() { // put drawing code here + background(155); + circle(200, 200, 50); } \ No newline at end of file diff --git a/src/core/friendly_errors/browser_errors.js b/src/core/friendly_errors/browser_errors.js index b0f0dfeca6..e8f860e879 100644 --- a/src/core/friendly_errors/browser_errors.js +++ b/src/core/friendly_errors/browser_errors.js @@ -15,6 +15,11 @@ const strings = { msg: "Can't find variable: {{}}", type: 'NOTDEFINED', browser: 'Safari' + }, + { + msg: "Cannot access '{{.}}' before initialization", + type: 'CANNOTACCESS', + browser: 'Chrome' } ], SyntaxError: [ @@ -42,6 +47,21 @@ const strings = { msg: "expected {{.}}, got '{{.}}'", type: 'UNEXPECTEDTOKEN', browser: 'Chrome' + }, + { + msg: "Identifier '{{.}}' has already been declared", + type: 'REDECLAREDVARIABLE', + browser: 'Chrome' + }, + { + msg: 'Missing initializer in const declaration', + type: 'MISSINGINITIALIZER', + browser: 'Chrome' + }, + { + msg: 'Illegal return statement', + type: 'BADRETURNORYIELD', + browser: 'Chrome' } ], TypeError: [ @@ -49,6 +69,21 @@ const strings = { msg: '{{.}} is not a function', type: 'NOTFUNC', browser: 'all' + }, + { + msg: "Cannot read property '{{.}}' of null", + type: 'READNULL', + browser: 'chrome' + }, + { + msg: "Cannot read property '{{.}}' of undefined", + type: 'READUDEFINED', + browser: 'chrome' + }, + { + msg: 'Assignment to constant variable', + type: 'CONSTASSIGN', + browser: 'chrome' } ] }; diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index fae46fb1c4..e3298d901a 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -731,6 +731,38 @@ if (typeof IS_MINIFIED !== 'undefined') { ); break; } + case 'REDECLAREDVARIABLE': { + let errSym = matchedError.match[1]; + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Redeclared_parameter#what_went_wrong'; + report( + translator('fes.globalErrors.syntax.redeclaredVariable', { + symbol: errSym, + url + }) + ); + break; + } + case 'MISSINGINITIALIZER': { + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_initializer_in_const#what_went_wrong'; + report( + translator('fes.globalErrors.syntax.missingInitializer', { + url + }) + ); + break; + } + case 'BADRETURNORYIELD': { + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_return_or_yield#what_went_wrong'; + report( + translator('fes.globalErrors.syntax.badReturnOrYield', { + url + }) + ); + break; + } } break; } @@ -762,6 +794,23 @@ if (typeof IS_MINIFIED !== 'undefined') { if (friendlyStack) printFriendlyStack(friendlyStack); break; } + case 'CANNOTACCESS': { + let errSym = matchedError.match[1]; + + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init#what_went_wrong'; + report( + translator('fes.globalErrors.reference.cannotAccess', { + url, + symbol: errSym, + location: locationObj + ? translator('fes.location', locationObj) + : '' + }) + ); + + break; + } } break; } @@ -800,6 +849,49 @@ if (typeof IS_MINIFIED !== 'undefined') { if (friendlyStack) printFriendlyStack(friendlyStack); break; } + case 'READNULL': { + let errSym = matchedError.match[1]; + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; + report( + translator('fes.globalErrors.type.readFromNullorUndefined', { + url, + symbol: errSym, + location: locationObj + ? translator('fes.location', locationObj) + : '' + }) + ); + break; + } + case 'READUDEFINED': { + let errSym = matchedError.match[1]; + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; + report( + translator('fes.globalErrors.type.readFromNullorUndefined', { + url, + symbol: errSym, + location: locationObj + ? translator('fes.location', locationObj) + : '' + }) + ); + break; + } + case 'CONSTASSIGN': { + let url = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_const_assignment#what_went_wrong'; + report( + translator('fes.globalErrors.type.constAssign', { + url, + location: locationObj + ? translator('fes.location', locationObj) + : '' + }) + ); + break; + } } } } diff --git a/translations/en/translation.json b/translations/en/translation.json index a997769c5a..14e9c177c1 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -22,17 +22,23 @@ }, "globalErrors": { "reference": { + "cannotAccess": "There's an error due to \"{{symbol}}\" being used before the initilization {{location}}.\n\nFor more:\n{{url}}", "notDefined": "There's an error due to \"{{symbol}}\" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" }, "stackSubseq": "▶️ Called from line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "stackTop": "▶️ Error at line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "syntax": { + "badReturnOrYield": "There's a syntax error due to a return or yield statement being called outside of a function.\nFor more: {{url}}", "invalidToken": "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", + "missingInitializer": "There's a syntax error due to a variable declated as a const not being initilized.\nFor more: {{url}}", + "redeclaredVariable": "There's a syntax error due to \"{{symbol}}\" being redefined.\nUsually this is due to a typo.\nFor more: {{url}}", "unexpectedToken": "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}" }, "type": { + "constAssign": "values to const variables should not be re-assigned \nat {{location}}.\nFor more: {{url}}", "notfunc": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", - "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}" + "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", + "readFromNullorUndefined": "There's an error as \"{{symbol}}\" could not be read from null/undefined \nat {{location}}.\nFor more: {{url}}" } }, "libraryError": "An error with message \"{{error}}\" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.", diff --git a/translations/es/translation.json b/translations/es/translation.json index fc81a53228..1bfc5e5c03 100644 --- a/translations/es/translation.json +++ b/translations/es/translation.json @@ -22,17 +22,26 @@ }, "globalErrors": { "reference": { - "notDefined": "" + "cannotAccess": "", + "notDefined": "", + "readNull": "" }, "stackSubseq": "", "stackTop": "", "syntax": { + "badReturnOrYield": "", "invalidToken": "", - "unexpectedToken": "" + "missingInitializer": "", + "redeclaredVariable": "", + "unexpectedToken": "", + "unexpectedToken ": "" }, "type": { + "constAssign": "", "notfunc": "", - "notfuncObj": "" + "notfuncObj": "", + "readFromNullorUndefined": "", + "readNull": "" } }, "libraryError": "", From bdedb308434b01c6676e1e83b5f37b7e690c71a7 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Fri, 21 May 2021 17:39:11 +0530 Subject: [PATCH 02/18] initial initial commit --- translations/es/translation.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/translations/es/translation.json b/translations/es/translation.json index 1bfc5e5c03..760086ccc3 100644 --- a/translations/es/translation.json +++ b/translations/es/translation.json @@ -33,8 +33,7 @@ "invalidToken": "", "missingInitializer": "", "redeclaredVariable": "", - "unexpectedToken": "", - "unexpectedToken ": "" + "unexpectedToken": "" }, "type": { "constAssign": "", From 67707db9dad0afff893bc1e43fc4a4ee88d2ad91 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Sat, 22 May 2021 12:54:25 +0530 Subject: [PATCH 03/18] add printFriendlyStack --- lib/empty-example/sketch.js | 9 +-------- src/core/friendly_errors/fes_core.js | 8 +++++++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/empty-example/sketch.js b/lib/empty-example/sketch.js index 5737f34b08..de6c862644 100644 --- a/lib/empty-example/sketch.js +++ b/lib/empty-example/sketch.js @@ -1,14 +1,7 @@ -console.log(a); -const a=100; - function setup() { // put setup code here - createCanvas(400, 400); - - } + function draw() { // put drawing code here - background(155); - circle(200, 200, 50); } \ No newline at end of file diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index e3298d901a..ba28905da8 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -796,7 +796,6 @@ if (typeof IS_MINIFIED !== 'undefined') { } case 'CANNOTACCESS': { let errSym = matchedError.match[1]; - let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init#what_went_wrong'; report( @@ -809,6 +808,7 @@ if (typeof IS_MINIFIED !== 'undefined') { }) ); + if (friendlyStack) printFriendlyStack(friendlyStack); break; } } @@ -862,6 +862,8 @@ if (typeof IS_MINIFIED !== 'undefined') { : '' }) ); + + if (friendlyStack) printFriendlyStack(friendlyStack); break; } case 'READUDEFINED': { @@ -877,6 +879,8 @@ if (typeof IS_MINIFIED !== 'undefined') { : '' }) ); + + if (friendlyStack) printFriendlyStack(friendlyStack); break; } case 'CONSTASSIGN': { @@ -890,6 +894,8 @@ if (typeof IS_MINIFIED !== 'undefined') { : '' }) ); + + if (friendlyStack) printFriendlyStack(friendlyStack); break; } } From 6b0d65cc5adccc3575310c08e15b4854a161cf6e Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Sat, 22 May 2021 16:19:09 +0530 Subject: [PATCH 04/18] add error templates for Firefox --- src/core/friendly_errors/browser_errors.js | 41 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/core/friendly_errors/browser_errors.js b/src/core/friendly_errors/browser_errors.js index e8f860e879..71b2149665 100644 --- a/src/core/friendly_errors/browser_errors.js +++ b/src/core/friendly_errors/browser_errors.js @@ -20,6 +20,11 @@ const strings = { msg: "Cannot access '{{.}}' before initialization", type: 'CANNOTACCESS', browser: 'Chrome' + }, + { + msg: "can't access lexical declaration '{{.}}' before initialization", + type: 'CANNOTACCESS', + browser: 'Firefox' } ], SyntaxError: [ @@ -53,15 +58,30 @@ const strings = { type: 'REDECLAREDVARIABLE', browser: 'Chrome' }, + { + msg: 'redeclaration of {} {{.}}', + type: 'REDECLAREDVARIABLE', + browser: 'Firefox' + }, { msg: 'Missing initializer in const declaration', type: 'MISSINGINITIALIZER', browser: 'Chrome' }, + { + msg: 'Missing = in const declaration', + type: 'MISSINGINITIALIZER', + browser: 'Firefox' + }, { msg: 'Illegal return statement', type: 'BADRETURNORYIELD', browser: 'Chrome' + }, + { + msg: 'return not in function', + type: 'BADRETURNORYIELD', + browser: 'Firefox' } ], TypeError: [ @@ -73,17 +93,32 @@ const strings = { { msg: "Cannot read property '{{.}}' of null", type: 'READNULL', - browser: 'chrome' + browser: 'Chrome' + }, + { + msg: '{{.}} is null', + type: 'READNULL', + browser: 'Firefox' }, { msg: "Cannot read property '{{.}}' of undefined", type: 'READUDEFINED', - browser: 'chrome' + browser: 'Chrome' + }, + { + msg: '{{.}} is undefined', + type: 'READUDEFINED', + browser: 'Firefox' }, { msg: 'Assignment to constant variable', type: 'CONSTASSIGN', - browser: 'chrome' + browser: 'Chrome' + }, + { + msg: "invalid assignment to const '{{.}}'", + type: 'CONSTASSIGN', + browser: 'Firefox' } ] }; From 564f629b319961d28b70bd5ba09a2be61d4303fb Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Wed, 26 May 2021 12:42:21 +0530 Subject: [PATCH 05/18] added extra urls in readnull and readundefined --- src/core/friendly_errors/fes_core.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index ba28905da8..07c603201b 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -851,11 +851,14 @@ if (typeof IS_MINIFIED !== 'undefined') { } case 'READNULL': { let errSym = matchedError.match[1]; - let url = + let url1 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; + let url2 = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null'; report( translator('fes.globalErrors.type.readFromNullorUndefined', { - url, + url1, + url2, symbol: errSym, location: locationObj ? translator('fes.location', locationObj) @@ -868,11 +871,14 @@ if (typeof IS_MINIFIED !== 'undefined') { } case 'READUDEFINED': { let errSym = matchedError.match[1]; - let url = + let url1 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; + let url2 = + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined#description'; report( translator('fes.globalErrors.type.readFromNullorUndefined', { - url, + url1, + url2, symbol: errSym, location: locationObj ? translator('fes.location', locationObj) From a07b678564a6f93727987af65d8ac198613d3558 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Tue, 1 Jun 2021 11:41:18 +0530 Subject: [PATCH 06/18] add friendly error messages and seperate readNullAndUndefined error message --- src/core/friendly_errors/browser_errors.js | 2 +- src/core/friendly_errors/fes_core.js | 4 ++-- translations/en/translation.json | 13 +++++++------ translations/es/translation.json | 7 +++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/friendly_errors/browser_errors.js b/src/core/friendly_errors/browser_errors.js index 71b2149665..6abdc4a4b3 100644 --- a/src/core/friendly_errors/browser_errors.js +++ b/src/core/friendly_errors/browser_errors.js @@ -69,7 +69,7 @@ const strings = { browser: 'Chrome' }, { - msg: 'Missing = in const declaration', + msg: 'missing = in const declaration', type: 'MISSINGINITIALIZER', browser: 'Firefox' }, diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index 07c603201b..6eda95742d 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -856,7 +856,7 @@ if (typeof IS_MINIFIED !== 'undefined') { let url2 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null'; report( - translator('fes.globalErrors.type.readFromNullorUndefined', { + translator('fes.globalErrors.type.readFromNull', { url1, url2, symbol: errSym, @@ -876,7 +876,7 @@ if (typeof IS_MINIFIED !== 'undefined') { let url2 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined#description'; report( - translator('fes.globalErrors.type.readFromNullorUndefined', { + translator('fes.globalErrors.type.readFromUndefined', { url1, url2, symbol: errSym, diff --git a/translations/en/translation.json b/translations/en/translation.json index 14e9c177c1..61c6517643 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -22,23 +22,24 @@ }, "globalErrors": { "reference": { - "cannotAccess": "There's an error due to \"{{symbol}}\" being used before the initilization {{location}}.\n\nFor more:\n{{url}}", + "cannotAccess": "There's an error due to \"{{symbol}}\" being used before initialization. Make sure you have initialized the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", "notDefined": "There's an error due to \"{{symbol}}\" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" }, "stackSubseq": "▶️ Called from line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "stackTop": "▶️ Error at line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "syntax": { - "badReturnOrYield": "There's a syntax error due to a return or yield statement being called outside of a function.\nFor more: {{url}}", + "badReturnOrYield": "There is a syntax error due to a return or yield statement being called outside of a function. Usually, there is a curly bracket missing somewhere. Also, make sure the return or yield statement is inside of a function.\nFor more: {{url}}", "invalidToken": "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", - "missingInitializer": "There's a syntax error due to a variable declated as a const not being initilized.\nFor more: {{url}}", - "redeclaredVariable": "There's a syntax error due to \"{{symbol}}\" being redefined.\nUsually this is due to a typo.\nFor more: {{url}}", + "missingInitializer": "There is a syntax error due to a const variable being declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which it's declared. Check the line number in the below error and assign the const variable a value.\nFor more: {{url}}", + "redeclaredVariable": "There is a syntax error due to \"{{symbol}}\" being redefined. JavaScript doesn't allow the redeclaration of the same variable. Check the line number in error below for redeclaration of the variable.\nFor more: {{url}}", "unexpectedToken": "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}" }, "type": { - "constAssign": "values to const variables should not be re-assigned \nat {{location}}.\nFor more: {{url}}", + "constAssign": "There's an error due to a const variable being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is not declared a const.\n{{location}}\nFor more: {{url}}", "notfunc": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", - "readFromNullorUndefined": "There's an error as \"{{symbol}}\" could not be read from null/undefined \nat {{location}}.\nFor more: {{url}}" + "readFromNull": "There's an error as the property of null can't be read.\nIn javascript the value null represents the intentional absence of any object value.\nFor more: \n{{url1}}\n{{url2}}", + "readFromUndefined": "There's an error as the property of something undefined can't be read. Check the line number in error below and make sure the variable which is being operated is not undefined there.\nFor more: \n{{url1}}\n{{url2}}" } }, "libraryError": "An error with message \"{{error}}\" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.", diff --git a/translations/es/translation.json b/translations/es/translation.json index 760086ccc3..a56e65eb24 100644 --- a/translations/es/translation.json +++ b/translations/es/translation.json @@ -23,8 +23,7 @@ "globalErrors": { "reference": { "cannotAccess": "", - "notDefined": "", - "readNull": "" + "notDefined": "" }, "stackSubseq": "", "stackTop": "", @@ -39,8 +38,8 @@ "constAssign": "", "notfunc": "", "notfuncObj": "", - "readFromNullorUndefined": "", - "readNull": "" + "readFromNull": "", + "readFromUndefined": "" } }, "libraryError": "", From 4b56f129e4b063c1cdc58fe2230f0848a90c3c23 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Wed, 16 Jun 2021 10:27:04 +0530 Subject: [PATCH 07/18] Update friendly error messages --- translations/en/translation.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/translations/en/translation.json b/translations/en/translation.json index 61c6517643..a5d64dc6dc 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -22,24 +22,24 @@ }, "globalErrors": { "reference": { - "cannotAccess": "There's an error due to \"{{symbol}}\" being used before initialization. Make sure you have initialized the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", + "cannotAccess": "\nError ▶️ \"{{symbol}}\" is used before initialization. Make sure you have initialized the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", "notDefined": "There's an error due to \"{{symbol}}\" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" }, "stackSubseq": "▶️ Called from line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "stackTop": "▶️ Error at line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "syntax": { - "badReturnOrYield": "There is a syntax error due to a return or yield statement being called outside of a function. Usually, there is a curly bracket missing somewhere. Also, make sure the return or yield statement is inside of a function.\nFor more: {{url}}", + "badReturnOrYield": "\nSyntax Error ▶️ `return` / `yield` lies outside of a function. Make sure you’re not missing any brackets, so that `return` / `yield` lies inside a function.\nFor more: {{url}}", "invalidToken": "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", - "missingInitializer": "There is a syntax error due to a const variable being declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which it's declared. Check the line number in the below error and assign the const variable a value.\nFor more: {{url}}", - "redeclaredVariable": "There is a syntax error due to \"{{symbol}}\" being redefined. JavaScript doesn't allow the redeclaration of the same variable. Check the line number in error below for redeclaration of the variable.\nFor more: {{url}}", + "missingInitializer": "\nSyntax Error ▶️ A const variable is declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which the variable is declared. Check the line number in the error below and assign the const variable a value.\nFor more: {{url}}", + "redeclaredVariable": "\nSyntax Error ▶️ \"{{symbol}}\" is being redefined. JavaScript doesn't allow declaring a variable more than once. Check the line number in error below for redeclaration of the variable.\nFor more: {{url}}", "unexpectedToken": "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}" }, "type": { - "constAssign": "There's an error due to a const variable being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is not declared a const.\n{{location}}\nFor more: {{url}}", + "constAssign": "\nError ▶️ A const variable is being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is not declared a const.\n{{location}}\nFor more: {{url}}", "notfunc": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", - "readFromNull": "There's an error as the property of null can't be read.\nIn javascript the value null represents the intentional absence of any object value.\nFor more: \n{{url1}}\n{{url2}}", - "readFromUndefined": "There's an error as the property of something undefined can't be read. Check the line number in error below and make sure the variable which is being operated is not undefined there.\nFor more: \n{{url1}}\n{{url2}}" + "readFromNull": "\nError ▶️ The property of null can't be read. In javascript the value null indicates that an object has no value.\nFor more: \n{{url1}}\n{{url2}}", + "readFromUndefined": "\nError ▶️ The property of something undefined can't be read. Check the line number in error below and make sure the variable which is being operated is not undefined.\nFor more: \n{{url1}}\n{{url2}}" } }, "libraryError": "An error with message \"{{error}}\" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.", From f1db41eb1be4f2b8bbd8f043b07ff220cab7d1c4 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Wed, 16 Jun 2021 10:54:41 +0530 Subject: [PATCH 08/18] add unit tests for new errors --- test/unit/core/error_helpers.js | 182 ++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 47e6a29d0e..e26915211e 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -705,6 +705,188 @@ suite('Global Error Handling', function() { }); }); + testUnMinified( + "correctly identifies ReferenceError 'cannotAccess'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /used before initialization/); + }); + } + ); + + testUnMinified( + "correctly identifies SyntaxError 'badReturnOrYield'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /lies outside of a function/); + }); + } + ); + + testUnMinified( + "correctly identifies SyntaxError 'missingInitializer'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /but not initialized/); + }); + } + ); + + testUnMinified( + "correctly identifies SyntaxError 'redeclaredVariable'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /JavaScript doesn't allow/); + }); + } + ); + + testUnMinified("correctly identifies TypeError 'constAssign'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /const variable is being/); + }); + }); + + testUnMinified("correctly identifies TypeError 'readFromNull'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /property of null/); + }); + }); + + testUnMinified( + "correctly identifies TypeError 'readFromUndefined'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /of something undefined/); + }); + } + ); + testUnMinified('correctly builds friendlyStack', function() { return new Promise(function(resolve) { iframe = createP5Iframe( From ffe276152e256e28fbcbedbe0aa7ed374d4b5a69 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Thu, 17 Jun 2021 10:34:05 +0530 Subject: [PATCH 09/18] add descriptive names to unit tests --- test/unit/core/error_helpers.js | 100 +++++++++++++++++--------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index e26915211e..7f48ad87d1 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -589,7 +589,7 @@ suite('Global Error Handling', function() { }); }); - testUnMinified('correctly identifies errors in user code I', function() { + testUnMinified("correctly identifies TypeError 'notDefined'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -612,53 +612,59 @@ suite('Global Error Handling', function() { }); }); - testUnMinified('correctly identifies errors in user code II', function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /syntax error/); - assert.match(log[0], /JavaScript doesn't recognize/); - }); - }); + testUnMinified( + "correctly identifies SyntaxError 'Invalid or unexpected Token'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /syntax error/); + assert.match(log[0], /JavaScript doesn't recognize/); + }); + } + ); - testUnMinified('correctly identifies errors in user code III', function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /syntax error/); - assert.match(log[0], /typo/); - }); - }); + testUnMinified( + "correctly identifies SyntaxError 'unexpectedToken'", + function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /syntax error/); + assert.match(log[0], /typo/); + }); + } + ); - testUnMinified('correctly identifies errors in user code IV', function() { + testUnMinified("correctly identifies TypeError 'notFunc'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -681,7 +687,7 @@ suite('Global Error Handling', function() { }); }); - testUnMinified('correctly identifies errors in user code IV', function() { + testUnMinified("correctly identifies TypeError 'notFuncObj'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ From 9eabe2a1032d25c5e2f929fc2af4cc2b3e4637d7 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Sat, 19 Jun 2021 08:23:00 +0530 Subject: [PATCH 10/18] Edit unit test names --- test/unit/core/error_helpers.js | 528 +++++++++++++++----------------- 1 file changed, 249 insertions(+), 279 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 7f48ad87d1..78124888f1 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -532,39 +532,36 @@ suite('Global Error Handling', function() { p5._fesLogger = null; }); - testUnMinified( - 'correctly identifies errors happenning internally', - function() { - return new Promise(function(resolve) { - // quite an unusual way to test, but the error listerner doesn't work - // under mocha. Also the stacktrace gets filled with mocha internal - // function calls. Using this method solves both of these problems. - // This method also allows us to test for SyntaxError without messing - // with flow of the other tests - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /inside the p5js library/); - assert.match(log[0], /mouseClicked/); - }); - } - ); + testUnMinified('identifies errors happenning internally', function() { + return new Promise(function(resolve) { + // quite an unusual way to test, but the error listerner doesn't work + // under mocha. Also the stacktrace gets filled with mocha internal + // function calls. Using this method solves both of these problems. + // This method also allows us to test for SyntaxError without messing + // with flow of the other tests + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /inside the p5js library/); + assert.match(log[0], /mouseClicked/); + }); + }); - testUnMinified('correctly identifies errors in preload', function() { + testUnMinified('identifies errors in preload', function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -589,7 +586,7 @@ suite('Global Error Handling', function() { }); }); - testUnMinified("correctly identifies TypeError 'notDefined'", function() { + testUnMinified("identifies TypeError 'notDefined'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -613,7 +610,7 @@ suite('Global Error Handling', function() { }); testUnMinified( - "correctly identifies SyntaxError 'Invalid or unexpected Token'", + "identifies SyntaxError 'Invalid or unexpected Token'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( @@ -638,33 +635,30 @@ suite('Global Error Handling', function() { } ); - testUnMinified( - "correctly identifies SyntaxError 'unexpectedToken'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /syntax error/); - assert.match(log[0], /typo/); - }); - } - ); + testUnMinified("identifies SyntaxError 'unexpectedToken'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /syntax error/); + assert.match(log[0], /typo/); + }); + }); - testUnMinified("correctly identifies TypeError 'notFunc'", function() { + testUnMinified("identifies TypeError 'notFunc'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -687,7 +681,7 @@ suite('Global Error Handling', function() { }); }); - testUnMinified("correctly identifies TypeError 'notFuncObj'", function() { + testUnMinified("identifies TypeError 'notFuncObj'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -711,114 +705,102 @@ suite('Global Error Handling', function() { }); }); - testUnMinified( - "correctly identifies ReferenceError 'cannotAccess'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /Error/); - assert.match(log[0], /used before initialization/); - }); - } - ); + testUnMinified("identifies ReferenceError 'cannotAccess'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /used before initialization/); + }); + }); - testUnMinified( - "correctly identifies SyntaxError 'badReturnOrYield'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /Syntax Error/); - assert.match(log[0], /lies outside of a function/); - }); - } - ); + testUnMinified("identifies SyntaxError 'badReturnOrYield'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /lies outside of a function/); + }); + }); - testUnMinified( - "correctly identifies SyntaxError 'missingInitializer'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /Syntax Error/); - assert.match(log[0], /but not initialized/); - }); - } - ); + testUnMinified("identifies SyntaxError 'missingInitializer'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /but not initialized/); + }); + }); - testUnMinified( - "correctly identifies SyntaxError 'redeclaredVariable'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /Syntax Error/); - assert.match(log[0], /JavaScript doesn't allow/); - }); - } - ); + testUnMinified("identifies SyntaxError 'redeclaredVariable'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Syntax Error/); + assert.match(log[0], /JavaScript doesn't allow/); + }); + }); - testUnMinified("correctly identifies TypeError 'constAssign'", function() { + testUnMinified("identifies TypeError 'constAssign'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -842,7 +824,7 @@ suite('Global Error Handling', function() { }); }); - testUnMinified("correctly identifies TypeError 'readFromNull'", function() { + testUnMinified("identifies TypeError 'readFromNull'", function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -866,34 +848,31 @@ suite('Global Error Handling', function() { }); }); - testUnMinified( - "correctly identifies TypeError 'readFromUndefined'", - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /Error/); - assert.match(log[0], /of something undefined/); - }); - } - ); + testUnMinified("identifies TypeError 'readFromUndefined'", function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /Error/); + assert.match(log[0], /of something undefined/); + }); + }); - testUnMinified('correctly builds friendlyStack', function() { + testUnMinified('builds friendlyStack', function() { return new Promise(function(resolve) { iframe = createP5Iframe( [ @@ -925,92 +904,83 @@ suite('Global Error Handling', function() { }); }); - testUnMinified( - 'correctly indentifies internal error - instance mode', - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /stroke/); - assert.match(log[0], /inside the p5js library/); - }); - } - ); + testUnMinified('indentifies internal error - instance mode', function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /stroke/); + assert.match(log[0], /inside the p5js library/); + }); + }); - testUnMinified( - 'correctly indentifies error in preload - instance mode', - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /"circle" being called from preload/); - }); - } - ); + testUnMinified('indentifies error in preload - instance mode', function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /"circle" being called from preload/); + }); + }); - testUnMinified( - 'correctly indentifies error in user code - instance mode', - function() { - return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') - ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; - }).then(function() { - assert.strictEqual(log.length, 1); - assert.match(log[0], /myfun/); - assert.match(log[0], /not being defined in the current scope/); - }); - } - ); + testUnMinified('indentifies error in user code - instance mode', function() { + return new Promise(function(resolve) { + iframe = createP5Iframe( + [ + P5_SCRIPT_TAG, + WAIT_AND_RESOLVE, + '' + ].join('\n') + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + }).then(function() { + assert.strictEqual(log.length, 1); + assert.match(log[0], /myfun/); + assert.match(log[0], /not being defined in the current scope/); + }); + }); }); From ec3b2b7ba47be069af4088463087f4f77765afac Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Sat, 19 Jun 2021 09:41:23 +0530 Subject: [PATCH 11/18] unit test failure test --- test/unit/core/error_helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 78124888f1..8d812120e4 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -713,8 +713,8 @@ suite('Global Error Handling', function() { WAIT_AND_RESOLVE, '' ].join('\n') From 63ce561640ad18c5f31515db3ef572c1fc2a1fce Mon Sep 17 00:00:00 2001 From: evelyn masso Date: Sun, 20 Jun 2021 11:36:56 -0700 Subject: [PATCH 12/18] replace report() with p5._friendlyError() --- src/core/friendly_errors/fes_core.js | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index 6eda95742d..bb24fb3736 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -354,7 +354,7 @@ if (typeof IS_MINIFIED !== 'undefined') { actualName: fxns[lowercase] }); - report(msg, fxns[lowercase]); + p5._friendlyError(msg, fxns[lowercase]); } } }; @@ -454,7 +454,7 @@ if (typeof IS_MINIFIED !== 'undefined') { // a link to the reference documentation. In case of multiple matches, // this is already done in the suggestions variable, one link for each // suggestion. - report( + p5._friendlyError( msg, matchedSymbols.length === 1 ? matchedSymbols[0].name : undefined ); @@ -601,7 +601,7 @@ if (typeof IS_MINIFIED !== 'undefined') { currentEntryPoint === 'preload' && p5.prototype._preloadMethods[func] == null ) { - report( + p5._friendlyError( translator('fes.wrongPreload', { func: func, location: locationObj @@ -613,7 +613,7 @@ if (typeof IS_MINIFIED !== 'undefined') { ); } else { // Library error - report( + p5._friendlyError( translator('fes.libraryError', { func: func, location: locationObj @@ -714,7 +714,7 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'INVALIDTOKEN': { let url = 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Illegal_character#What_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.syntax.invalidToken', { url }) @@ -724,7 +724,7 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'UNEXPECTEDTOKEN': { let url = 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Unexpected_token#What_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.syntax.unexpectedToken', { url }) @@ -735,7 +735,7 @@ if (typeof IS_MINIFIED !== 'undefined') { let errSym = matchedError.match[1]; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Redeclared_parameter#what_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.syntax.redeclaredVariable', { symbol: errSym, url @@ -746,7 +746,7 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'MISSINGINITIALIZER': { let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_initializer_in_const#what_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.syntax.missingInitializer', { url }) @@ -756,7 +756,7 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'BADRETURNORYIELD': { let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_return_or_yield#what_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.syntax.badReturnOrYield', { url }) @@ -780,7 +780,7 @@ if (typeof IS_MINIFIED !== 'undefined') { let url1 = 'https://p5js.org/examples/data-variable-scope.html'; let url2 = 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_Defined#What_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.reference.notDefined', { url1, url2, @@ -798,7 +798,7 @@ if (typeof IS_MINIFIED !== 'undefined') { let errSym = matchedError.match[1]; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init#what_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.reference.cannotAccess', { url, symbol: errSym, @@ -837,11 +837,11 @@ if (typeof IS_MINIFIED !== 'undefined') { // as a property of an object and when it's called independently. // Both have different explanations. if (splitSym.length > 1) { - report( + p5._friendlyError( translator('fes.globalErrors.type.notfuncObj', translationObj) ); } else { - report( + p5._friendlyError( translator('fes.globalErrors.type.notfunc', translationObj) ); } @@ -855,7 +855,7 @@ if (typeof IS_MINIFIED !== 'undefined') { 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; let url2 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null'; - report( + p5._friendlyError( translator('fes.globalErrors.type.readFromNull', { url1, url2, @@ -875,7 +875,7 @@ if (typeof IS_MINIFIED !== 'undefined') { 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; let url2 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined#description'; - report( + p5._friendlyError( translator('fes.globalErrors.type.readFromUndefined', { url1, url2, @@ -892,7 +892,7 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'CONSTASSIGN': { let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_const_assignment#what_went_wrong'; - report( + p5._friendlyError( translator('fes.globalErrors.type.constAssign', { url, location: locationObj From 86561c59c489a2d2e30c9efb1b077255917220f4 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Mon, 28 Jun 2021 13:42:27 +0530 Subject: [PATCH 13/18] added comments explaning the type of errors --- src/core/friendly_errors/fes_core.js | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index 34875cd22c..c17adb5b4a 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -712,6 +712,8 @@ if (typeof IS_MINIFIED !== 'undefined') { // for syntax errors switch (matchedError.type) { case 'INVALIDTOKEN': { + //Error if there is an invalid or unexpected token that doesn't belong at this position in the code + //let x = “not a string”; -> string not in proper quotes let url = 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Illegal_character#What_went_wrong'; p5._friendlyError( @@ -722,6 +724,8 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'UNEXPECTEDTOKEN': { + //Error if a specific language construct(, { ; etc) was expected, but something else was provided + //for (let i = 0; i < 5,; ++i) -> a comma after i<5 instead of a semicolon let url = 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Unexpected_token#What_went_wrong'; p5._friendlyError( @@ -732,6 +736,9 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'REDECLAREDVARIABLE': { + //Error if a variable is redeclared by the user. Example=> + //let a = 10; + //let a = 100; let errSym = matchedError.match[1]; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Redeclared_parameter#what_went_wrong'; @@ -744,6 +751,8 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'MISSINGINITIALIZER': { + //Error if a const variable is not initialized during declaration + //Example => const a; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_initializer_in_const#what_went_wrong'; p5._friendlyError( @@ -754,6 +763,11 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'BADRETURNORYIELD': { + //Error when a return statement is misplaced(usually outside of a function) + // const a = function(){ + // ..... + // } + // return; -> misplaced return statement let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_return_or_yield#what_went_wrong'; p5._friendlyError( @@ -769,6 +783,9 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'ReferenceError': { switch (matchedError.type) { case 'NOTDEFINED': { + //Error if there is a non-existent variable referenced somewhere + //let a = 10; + //console.log(x); let errSym = matchedError.match[1]; if (errSym && handleMisspelling(errSym, error)) { @@ -795,6 +812,9 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'CANNOTACCESS': { + //Error if a lexical variable was accessed before it was initialized + //console.log(a); -> variable accessed before it was initialized + //let a=100; let errSym = matchedError.match[1]; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init#what_went_wrong'; @@ -818,6 +838,8 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'TypeError': { switch (matchedError.type) { case 'NOTFUNC': { + //Error when some code expects you to provide a function, but that didn't happen + //let a = document.getElementByID('foo'); -> getElementById instead of getElementByID let errSym = matchedError.match[1]; let splitSym = errSym.split('.'); let url = @@ -850,6 +872,9 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'READNULL': { + //Error if a property of null is accessed + //let a = null; + //console.log(a.property); -> a is null let errSym = matchedError.match[1]; let url1 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; @@ -870,6 +895,9 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'READUDEFINED': { + //Error if a property of undefined is accessed + //let a; -> default value of a is undefined + //console.log(a.property); -> a is undefined let errSym = matchedError.match[1]; let url1 = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property#what_went_wrong'; @@ -890,6 +918,9 @@ if (typeof IS_MINIFIED !== 'undefined') { break; } case 'CONSTASSIGN': { + //Error when a const variable is reassigned a value + //const a = 100; + //a=10; let url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_const_assignment#what_went_wrong'; p5._friendlyError( From f88ca684603ce1c0829eb55613f1916491bb1747 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Wed, 30 Jun 2021 14:32:46 +0530 Subject: [PATCH 14/18] update the error messages --- translations/en/translation.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/en/translation.json b/translations/en/translation.json index 56ed103e87..c2bd6530f4 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -22,16 +22,16 @@ }, "globalErrors": { "reference": { - "cannotAccess": "\nError ▶️ \"{{symbol}}\" is used before initialization. Make sure you have initialized the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", + "cannotAccess": "\nError ▶️ \"{{symbol}}\" is used before declaration. Make sure you have declared the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", "notDefined": "There's an error due to \"{{symbol}}\" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" }, "stackSubseq": "▶️ Called from line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "stackTop": "▶️ Error at line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "syntax": { - "badReturnOrYield": "\nSyntax Error ▶️ `return` / `yield` lies outside of a function. Make sure you’re not missing any brackets, so that `return` / `yield` lies inside a function.\nFor more: {{url}}", + "badReturnOrYield": "\nSyntax Error ▶️ return lies outside of a function. Make sure you’re not missing any brackets, so that return lies inside a function.\nFor more: {{url}}", "invalidToken": "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", - "missingInitializer": "\nSyntax Error ▶️ A const variable is declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which the variable is declared. Check the line number in the error below and assign the const variable a value.\nFor more: {{url}}", - "redeclaredVariable": "\nSyntax Error ▶️ \"{{symbol}}\" is being redefined. JavaScript doesn't allow declaring a variable more than once. Check the line number in error below for redeclaration of the variable.\nFor more: {{url}}", + "missingInitializer": "\nSyntax Error ▶️ A const variable is declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which the variable is declared. Check the line number in the error and assign the const variable a value.\nFor more: {{url}}", + "redeclaredVariable": "\nSyntax Error ▶️ \"{{symbol}}\" is being redeclared. JavaScript doesn't allow declaring a variable more than once. Check the line number in error for redeclaration of the variable.\nFor more: {{url}}", "unexpectedToken": "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}" }, "type": { @@ -39,7 +39,7 @@ "notfunc": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "readFromNull": "\nError ▶️ The property of null can't be read. In javascript the value null indicates that an object has no value.\nFor more: \n{{url1}}\n{{url2}}", - "readFromUndefined": "\nError ▶️ The property of something undefined can't be read. Check the line number in error below and make sure the variable which is being operated is not undefined.\nFor more: \n{{url1}}\n{{url2}}" + "readFromUndefined": "\nError ▶️ The property of something undefined can't be read. Check the line number in error and make sure the variable which is being operated is not undefined.\nFor more: \n{{url1}}\n{{url2}}" } }, "libraryError": "An error with message \"{{error}}\" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.", From eabd313bb06977ddb004562381df26cb8c23a980 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Wed, 30 Jun 2021 14:46:15 +0530 Subject: [PATCH 15/18] fix minor error which was failing the unit tests --- test/unit/core/error_helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 8d812120e4..d4ce36d817 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -725,7 +725,7 @@ suite('Global Error Handling', function() { }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); - assert.match(log[0], /used before initialization/); + assert.match(log[0], /used before declaration/); }); }); From fa62b17e7b7f6f57a603c090f20156bc61f69d43 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Mon, 5 Jul 2021 10:56:19 +0530 Subject: [PATCH 16/18] update friendly error messages --- test/unit/core/error_helpers.js | 12 ++++++------ translations/en/translation.json | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index d4ce36d817..55493c4fca 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -605,7 +605,7 @@ suite('Global Error Handling', function() { }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /asdfg/); - assert.match(log[0], /not being defined in the current scope/); + assert.match(log[0], /not defined in the current scope/); }); }); @@ -629,7 +629,7 @@ suite('Global Error Handling', function() { iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); - assert.match(log[0], /syntax error/); + assert.match(log[0], /Syntax Error/); assert.match(log[0], /JavaScript doesn't recognize/); }); } @@ -653,7 +653,7 @@ suite('Global Error Handling', function() { iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); - assert.match(log[0], /syntax error/); + assert.match(log[0], /Syntax Error/); assert.match(log[0], /typo/); }); }); @@ -868,7 +868,7 @@ suite('Global Error Handling', function() { }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); - assert.match(log[0], /of something undefined/); + assert.match(log[0], /property of undefined/); }); }); @@ -896,7 +896,7 @@ suite('Global Error Handling', function() { let temp = log[1].split('\n'); temp = temp.filter(e => e.trim().length > 0); assert.strictEqual(temp.length, 2); - assert.match(log[0], /"asdfg" not being defined/); + assert.match(log[0], /"asdfg" is not defined/); assert.match(temp[0], /Error at/); assert.match(temp[0], /myfun/); assert.match(temp[1], /Called from/); @@ -980,7 +980,7 @@ suite('Global Error Handling', function() { }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /myfun/); - assert.match(log[0], /not being defined in the current scope/); + assert.match(log[0], /is not defined in the current scope/); }); }); }); diff --git a/translations/en/translation.json b/translations/en/translation.json index c2bd6530f4..e9af3ad279 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -23,23 +23,23 @@ "globalErrors": { "reference": { "cannotAccess": "\nError ▶️ \"{{symbol}}\" is used before declaration. Make sure you have declared the variable before using it.\n\n{{location}}\n\nFor more: {{url}}", - "notDefined": "There's an error due to \"{{symbol}}\" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" + "notDefined": "\nError ▶️ \"{{symbol}}\" is not defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}" }, "stackSubseq": "▶️ Called from line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "stackTop": "▶️ Error at line {{line}} in \"{{func}}\" in {{file}} ({{location}})\n\n", "syntax": { "badReturnOrYield": "\nSyntax Error ▶️ return lies outside of a function. Make sure you’re not missing any brackets, so that return lies inside a function.\nFor more: {{url}}", - "invalidToken": "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", + "invalidToken": "\nSyntax Error ▶️ Found a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}", "missingInitializer": "\nSyntax Error ▶️ A const variable is declared but not initialized. In JavaScript, an initializer for a const is required. A value must be specified in the same statement in which the variable is declared. Check the line number in the error and assign the const variable a value.\nFor more: {{url}}", "redeclaredVariable": "\nSyntax Error ▶️ \"{{symbol}}\" is being redeclared. JavaScript doesn't allow declaring a variable more than once. Check the line number in error for redeclaration of the variable.\nFor more: {{url}}", - "unexpectedToken": "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}" + "unexpectedToken": "\nSyntax Error ▶️ Symbol present at a place that wasn't expected.\nUsually this is due to a typo. Check the line number in the error for anything missing/extra.\nFor more: {{url}}" }, "type": { "constAssign": "\nError ▶️ A const variable is being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is not declared a const.\n{{location}}\nFor more: {{url}}", - "notfunc": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", - "notfuncObj": "There's an error as \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", + "notfunc": "\nError ▶️ \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", + "notfuncObj": "\nError ▶️ \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "readFromNull": "\nError ▶️ The property of null can't be read. In javascript the value null indicates that an object has no value.\nFor more: \n{{url1}}\n{{url2}}", - "readFromUndefined": "\nError ▶️ The property of something undefined can't be read. Check the line number in error and make sure the variable which is being operated is not undefined.\nFor more: \n{{url1}}\n{{url2}}" + "readFromUndefined": "\nError ▶️ Cannot read property of undefined. Check the line number in error and make sure the variable which is being operated is not undefined.\nFor more: \n{{url1}}\n{{url2}}" } }, "libraryError": "An error with message \"{{error}}\" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.", From 859847fe565560ee49f2c287057d9f40ee06feaa Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Tue, 6 Jul 2021 11:01:21 +0530 Subject: [PATCH 17/18] removed typo and updated the message" --- test/unit/core/error_helpers.js | 2 +- translations/en/translation.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 55493c4fca..4747abba0a 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -534,7 +534,7 @@ suite('Global Error Handling', function() { testUnMinified('identifies errors happenning internally', function() { return new Promise(function(resolve) { - // quite an unusual way to test, but the error listerner doesn't work + // quite an unusual way to test, but the error listener doesn't work // under mocha. Also the stacktrace gets filled with mocha internal // function calls. Using this method solves both of these problems. // This method also allows us to test for SyntaxError without messing diff --git a/translations/en/translation.json b/translations/en/translation.json index e9af3ad279..03e2d4ae20 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -35,7 +35,7 @@ "unexpectedToken": "\nSyntax Error ▶️ Symbol present at a place that wasn't expected.\nUsually this is due to a typo. Check the line number in the error for anything missing/extra.\nFor more: {{url}}" }, "type": { - "constAssign": "\nError ▶️ A const variable is being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is not declared a const.\n{{location}}\nFor more: {{url}}", + "constAssign": "\nError ▶️ A const variable is being re-assigned. In javascript, re-assigning a value to a constant is not allowed. If you want to re-assign new values to a variable, make sure it is declared as var or let.\n{{location}}\nFor more: {{url}}", "notfunc": "\nError ▶️ \"{{symbol}}\" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "notfuncObj": "\nError ▶️ \"{{symbol}}\" could not be called as a function {{location}}.\nVerify whether \"{{obj}}\" has \"{{symbol}}\" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.\nFor more: {{url}}", "readFromNull": "\nError ▶️ The property of null can't be read. In javascript the value null indicates that an object has no value.\nFor more: \n{{url1}}\n{{url2}}", From 8d9964cf30502ba3ae1c4902cc70c1bc093acee3 Mon Sep 17 00:00:00 2001 From: Shantanu Kaushik Date: Tue, 6 Jul 2021 12:17:46 +0530 Subject: [PATCH 18/18] refactor global error handlingunit tests --- test/unit/core/error_helpers.js | 267 ++++++++++---------------------- 1 file changed, 83 insertions(+), 184 deletions(-) diff --git a/test/unit/core/error_helpers.js b/test/unit/core/error_helpers.js index 4747abba0a..139b40dd85 100644 --- a/test/unit/core/error_helpers.js +++ b/test/unit/core/error_helpers.js @@ -532,6 +532,18 @@ suite('Global Error Handling', function() { p5._fesLogger = null; }); + const prepSyntaxTest = (arr, resolve) => { + iframe = createP5Iframe( + [P5_SCRIPT_TAG, WAIT_AND_RESOLVE, ''].join( + '\n' + ) + ); + log = []; + iframe.elt.contentWindow.logger = logger; + iframe.elt.contentWindow.afterSetup = resolve; + return iframe; + }; + testUnMinified('identifies errors happenning internally', function() { return new Promise(function(resolve) { // quite an unusual way to test, but the error listener doesn't work @@ -539,21 +551,15 @@ suite('Global Error Handling', function() { // function calls. Using this method solves both of these problems. // This method also allows us to test for SyntaxError without messing // with flow of the other tests - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /inside the p5js library/); @@ -563,23 +569,17 @@ suite('Global Error Handling', function() { testUnMinified('identifies errors in preload', function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /"circle" being called from preload/); @@ -588,20 +588,14 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'notDefined'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /asdfg/); @@ -613,20 +607,14 @@ suite('Global Error Handling', function() { "identifies SyntaxError 'Invalid or unexpected Token'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Syntax Error/); @@ -637,20 +625,14 @@ suite('Global Error Handling', function() { testUnMinified("identifies SyntaxError 'unexpectedToken'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Syntax Error/); @@ -660,21 +642,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'notFunc'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /"asdfg" could not be called as a function/); @@ -683,21 +659,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'notFuncObj'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /"abcd" could not be called as a function/); @@ -707,21 +677,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies ReferenceError 'cannotAccess'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); @@ -731,21 +695,10 @@ suite('Global Error Handling', function() { testUnMinified("identifies SyntaxError 'badReturnOrYield'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( - [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + prepSyntaxTest( + ['function setup() {', 'let x = 100;', '}', 'return;'], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Syntax Error/); @@ -755,20 +708,14 @@ suite('Global Error Handling', function() { testUnMinified("identifies SyntaxError 'missingInitializer'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Syntax Error/); @@ -778,21 +725,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies SyntaxError 'redeclaredVariable'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Syntax Error/); @@ -802,21 +743,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'constAssign'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); @@ -826,21 +761,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'readFromNull'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); @@ -850,21 +779,15 @@ suite('Global Error Handling', function() { testUnMinified("identifies TypeError 'readFromUndefined'", function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /Error/); @@ -874,23 +797,17 @@ suite('Global Error Handling', function() { testUnMinified('builds friendlyStack', function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + '}' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 2); let temp = log[1].split('\n'); @@ -906,23 +823,17 @@ suite('Global Error Handling', function() { testUnMinified('indentifies internal error - instance mode', function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + 'new p5(sketch);' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /stroke/); @@ -932,11 +843,8 @@ suite('Global Error Handling', function() { testUnMinified('indentifies error in preload - instance mode', function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + 'new p5(sketch);' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /"circle" being called from preload/); @@ -960,23 +865,17 @@ suite('Global Error Handling', function() { testUnMinified('indentifies error in user code - instance mode', function() { return new Promise(function(resolve) { - iframe = createP5Iframe( + prepSyntaxTest( [ - P5_SCRIPT_TAG, - WAIT_AND_RESOLVE, - '' - ].join('\n') + 'new p5(sketch);' + ], + resolve ); - log = []; - iframe.elt.contentWindow.logger = logger; - iframe.elt.contentWindow.afterSetup = resolve; }).then(function() { assert.strictEqual(log.length, 1); assert.match(log[0], /myfun/);