diff --git a/src/core/friendly_errors/fes_core.js b/src/core/friendly_errors/fes_core.js index 5f9114a071..2414be0a5e 100644 --- a/src/core/friendly_errors/fes_core.js +++ b/src/core/friendly_errors/fes_core.js @@ -201,6 +201,31 @@ if (typeof IS_MINIFIED !== 'undefined') { p5._report(message, func, color); }; + /** + * This can be called from anywhere in the p5 library to show users + * a localized error message. Instead of passing the message itself, we + * pass a "key" that refers to a message contained in our bank of + * translations for all our supported languages (including English). (See + * `/translations/en/translation.json`). + * + * This works well for simple messages. If you want to do something more complex + * (like include a filename from an error), you'll need to use translator() and + * p5._friendlyError() together. + * + * @method _friendlyLocalizedError + * @private + * @param {String} messageKey Key to localized message to be printed + * @param {String} [func] Name of the function linked to error + * @param {Number|String} [color] CSS color code + */ + p5._friendlyLocalizedError = function(messageKey, func, color) { + // in the future we could support more direct calls to translator() + // to support extra arguments for complex messages + // by adding a typeof if statement on messageKey + const message = translator(messageKey); + p5._report(message, func, color); + }; + /** * This is called internally if there is an error with autoplay. Generates * and prints a friendly error message [fes.autoplay]. @@ -213,7 +238,7 @@ if (typeof IS_MINIFIED !== 'undefined') { src, url: 'https://developer.mozilla.org/docs/Web/Media/Autoplay_guide' }); - console.log(translator('fes.pre', { message })); + p5._friendlyLocalizedError(message); }; /** diff --git a/src/core/shape/vertex.js b/src/core/shape/vertex.js index b6abe9aec6..5ad900d4aa 100644 --- a/src/core/shape/vertex.js +++ b/src/core/shape/vertex.js @@ -391,8 +391,8 @@ p5.prototype.bezierVertex = function(...args) { this._renderer.bezierVertex(...args); } else { if (vertices.length === 0) { - p5._friendlyError( - 'vertex() must be used once before calling bezierVertex()', + p5._friendlyLocalizedError( + '', 'bezierVertex' ); } else { diff --git a/src/webgl/p5.Geometry.js b/src/webgl/p5.Geometry.js index d18f29f2da..30f17b4416 100644 --- a/src/webgl/p5.Geometry.js +++ b/src/webgl/p5.Geometry.js @@ -122,9 +122,9 @@ p5.Geometry = class { const ln = p5.Vector.mag(n); let sinAlpha = ln / (p5.Vector.mag(ab) * p5.Vector.mag(ac)); if (sinAlpha === 0 || isNaN(sinAlpha)) { - console.warn( - 'p5.Geometry.prototype._getFaceNormal:', - 'face has colinear sides or a repeated vertex' + p5._friendlyLocalizedError( + 'geometry.colinearSidesOrRepeatedVertex', + 'p5.Geometry.prototype._getFaceNormal:' ); return n; } diff --git a/test/unit/core/vertex.js b/test/unit/core/vertex.js index 1d58167d88..aac6a7560c 100644 --- a/test/unit/core/vertex.js +++ b/test/unit/core/vertex.js @@ -1,8 +1,8 @@ suite('Vertex', function() { var myp5; - let _friendlyErrorSpy; + let _friendlyLocalizedErrorSpy; setup(function(done) { - _friendlyErrorSpy = sinon.spy(p5, '_friendlyError'); + _friendlyLocalizedErrorSpy = sinon.spy(p5, '_friendlyLocalizedError'); new p5(function(p) { p.setup = function() { myp5 = p; @@ -12,7 +12,7 @@ suite('Vertex', function() { }); teardown(function() { - _friendlyErrorSpy.restore(); + _friendlyLocalizedErrorSpy.restore(); myp5.remove(); }); @@ -59,7 +59,7 @@ suite('Vertex', function() { }); test('_friendlyError is called. vertex() should be used once before quadraticVertex()', function() { myp5.quadraticVertex(80, 20, 50, 50, 10, 20); - assert(_friendlyErrorSpy.calledOnce, 'p5._friendlyError was not called'); + assert(_friendlyLocalizedErrorSpy.calledOnce, 'p5._friendlyError was not called'); }); }); @@ -80,7 +80,7 @@ suite('Vertex', function() { }); test('_friendlyError is called. vertex() should be used once before bezierVertex()', function() { myp5.bezierVertex(25, 30, 25, -30, -25, 30); - assert(_friendlyErrorSpy.calledOnce, 'p5._friendlyError was not called'); + assert(_friendlyLocalizedErrorSpy.calledOnce, 'p5._friendlyError was not called'); }); }); diff --git a/translations/en/translation.json b/translations/en/translation.json index 46257d487a..d84901748a 100644 --- a/translations/en/translation.json +++ b/translations/en/translation.json @@ -68,5 +68,11 @@ }, "welcome": "Welcome! This is your friendly debugger. To turn me off, switch to using p5.min.js.", "wrongPreload": "{{location}} An error with message \"{{error}}\" occurred inside the p5js library when \"{{func}}\" was called. If not stated otherwise, it might be due to \"{{func}}\" being called from preload. Nothing besides load calls (loadImage, loadJSON, loadFont, loadStrings, etc.) should be inside the preload function." + }, + "webgl": { + "colinearSidesOrRepeatedVertex": "face has colinear sides or a repeated vertex." + }, + "shape": { + "vertexBeforeBezierVertex": "vertex() must be used once before calling bezierVertex()" } }