Increasing access
By extending the interface of FES to be used by addons, addons and sketch authors can benefit from better and more helpful error messages that follows best practice with minimal effort.
Most appropriate sub-area of p5.js?
Feature enhancement details
I have been working on this for awhile and it is likely close to ready (not necessarily complete, just ready for basic use). There are many parts to this and I would like to solicit public comments at this point to see if the proposed API and implementation makes sense.
Overview
FES is a relatively complex system with many moving parts contributed by many contributors over the years. If we are to break it down into concrete parts, they are:
- Parameter validation - check types of arguments passed to p5.js functions at runtime
- Sketch verifier - check that user defined variables are not conflicting with p5.js globals with AST parsing
- Global error monitor - Read any uncaught error/exception thrown by the browser and print a useful message for it where possible
- General message printing - ie.
p5._friendlyError() function
The goal is to keep the external behavior the same (ie. same sketch with same error print the same or equivalent message) while updating the internal API and introduce new API for addons to use. Some parts also need updating for better ergonomics and bundle size optimization.
Translation
There is a complete rewrite of the translation utility used and instead of bundling i18next as a dependency (which is the fourth largest dependency by size in the minified build, representing 39 KB), I've written a new translation utility here: https://github.com/limzykenneth/tl-util (name TBD). By using the new translation utility the bundle size of the dependency in minified build goes down to 1.83 KB, the second smallest bundled dependency.
The file size is not the only consideration for the new utility, the API is the more significant difference. As part of this I'm exploring a different (and in my opinion better) way of working with translation string, I won't go into detail as that is documented in the README of the new utility, but to pick out the main point, using translated string instead of doing:
const username = "Alex";
const translatedString = translate("greeting", { name: username }); // What is the actual string??
it becomes the much more descriptive inline:
const username = "Alex";
const translatedString = tl`Hello and welcome ${username}!`;
Messages and their meaning are no longer opaque in source code needing a look up in translation data file to know what they are exactly but something that is present inline, and can be written in any language.
There will be an accompanying API for addon authors to add their FES message strings to the translation system and translators will be able to translate them. A more complex workflow and distribution system is still to come but planned. Translations will be fetched at runtime when needed, cached in local storage upon first run and users can even load their own if needed. There are still a bit more work to do here so I won't go into detail about the API because they are not 100% ready yet, but I will do so once I do a bit more planned implementation.
Printing message
Currently the way messages are printed in FES is typically by calling p5._friendlyError(), however in some other areas, different patterns are also used inconsistently. A downside to p5._friendlyError() is that the message is not translated automatically, you will have to explicitly use i18next while the interface to do that with p5.js internals is not exposed, meaning while addons can print message, it cannot be translated, by the author or by someone else. The browser console also has several useful features that are either not exposed, not documented, or difficult to use with p5._friendlyError() interface.
The new proposed interface provides a unified entrypoint p5.FES that has members analogous to browser console counterpart of p5.FES.log, p5.FES.warn etc. However, instead of being functions, they are tagged template literals. Essentially, they are expanded version of the translation utility above, meaning while defining the message you want to print, you are also enabling it to be translated automatically. The detail syntax is as below.
Translation strings can be nested as deep as necessary.
import { FES } from '../friendly_errors/fes.js';
// These creates translatable strings
const valueType = FES.log`number`;
const wrongType = FES.log`boolean`;
// This is just a plain string that will not be translated
const functionName = 'ellipse';
// By calling as a function, this prints the message translated
FES.log`Function ${functionName}() received ${wrongType} as argument but it expects ${valueType}`();
// Prints: Function ellipse() received boolean as argument but it expects ${number}
The below correspond to console.warn() and console.error() respectively but will translate if translation is available.
FES.warn`This is a warning message.`();
FES.error`Thisis an error message.`();
While not being used currently in FES, browser console let us style messages printed to the console. With the new API, we can also style messages but in a more inline way with API partially inspired by picocolors.
FES.log`The color is ${style('red', { color: '#FF0000' })} and ${style('blue', { color: '#0000FF'})}`();
All message is prefixed with '🌸 p5.js says: ' which itself can be translated, if the prefix is not desired or a different prefix is preferred, a prefix option can be passed:
FES.log`I have no prefix`({ prefix: false });
FES.log`The Fellowship of the Ring`({ prefix: 'The Lord of the Rings: ' });
Extending FES
With the message printing utility, extending FES typically is a matter for addon libraries to decide what they'd like to do with console messages for their own implementation, eg. the io module of p5.js gather its own errors received from trying to load files and print relevant messages with the FES API. There are room for extension within the existing FES features however, such as parameter validation, it would be great to have addon attached methods to also benefit from parameter validation the same way p5.js core functions are.
As such an API to extend parameter validation is provided as p5.extendParameterValidation(). This static method accept an argument of plain object that follows the parameter validation data structure:
{
p5: {
"circle": {
"overloads": [
[
"Number",
"Number",
"Number"
]
]
}
}
}
This adds the expected parameter type for the circle function to the parameter validation system. However, this is hard to author manually so the idea is to prepare tooling, likely in the form of a Rollup plugin (automatically included in the addon template), that will process and generate the necessary code for extending parameter validation. The addon author will need to write inline JSDoc documentation with relevant tag structure and on build, the plugin will parse the JSDoc information, pass it though the same code p5.js use to parse the parameter information and insert necessary code into the final bundle for parameter validation. The plugin part is still an early work in progress and it does not need to be completed for the other parts to be merged.
This is a request for comment, please leave any thoughts and review below! There already is a proof of concept implementation and I will file a PR for it soon, do not ask to be assigned
Increasing access
By extending the interface of FES to be used by addons, addons and sketch authors can benefit from better and more helpful error messages that follows best practice with minimal effort.
Most appropriate sub-area of p5.js?
Feature enhancement details
I have been working on this for awhile and it is likely close to ready (not necessarily complete, just ready for basic use). There are many parts to this and I would like to solicit public comments at this point to see if the proposed API and implementation makes sense.
Overview
FES is a relatively complex system with many moving parts contributed by many contributors over the years. If we are to break it down into concrete parts, they are:
p5._friendlyError()functionThe goal is to keep the external behavior the same (ie. same sketch with same error print the same or equivalent message) while updating the internal API and introduce new API for addons to use. Some parts also need updating for better ergonomics and bundle size optimization.
Translation
There is a complete rewrite of the translation utility used and instead of bundling i18next as a dependency (which is the fourth largest dependency by size in the minified build, representing 39 KB), I've written a new translation utility here: https://github.com/limzykenneth/tl-util (name TBD). By using the new translation utility the bundle size of the dependency in minified build goes down to 1.83 KB, the second smallest bundled dependency.
The file size is not the only consideration for the new utility, the API is the more significant difference. As part of this I'm exploring a different (and in my opinion better) way of working with translation string, I won't go into detail as that is documented in the README of the new utility, but to pick out the main point, using translated string instead of doing:
it becomes the much more descriptive inline:
Messages and their meaning are no longer opaque in source code needing a look up in translation data file to know what they are exactly but something that is present inline, and can be written in any language.
There will be an accompanying API for addon authors to add their FES message strings to the translation system and translators will be able to translate them. A more complex workflow and distribution system is still to come but planned. Translations will be fetched at runtime when needed, cached in local storage upon first run and users can even load their own if needed. There are still a bit more work to do here so I won't go into detail about the API because they are not 100% ready yet, but I will do so once I do a bit more planned implementation.
Printing message
Currently the way messages are printed in FES is typically by calling
p5._friendlyError(), however in some other areas, different patterns are also used inconsistently. A downside top5._friendlyError()is that the message is not translated automatically, you will have to explicitly use i18next while the interface to do that with p5.js internals is not exposed, meaning while addons can print message, it cannot be translated, by the author or by someone else. The browserconsolealso has several useful features that are either not exposed, not documented, or difficult to use withp5._friendlyError()interface.The new proposed interface provides a unified entrypoint
p5.FESthat has members analogous to browserconsolecounterpart ofp5.FES.log,p5.FES.warnetc. However, instead of being functions, they are tagged template literals. Essentially, they are expanded version of the translation utility above, meaning while defining the message you want to print, you are also enabling it to be translated automatically. The detail syntax is as below.Translation strings can be nested as deep as necessary.
The below correspond to
console.warn()andconsole.error()respectively but will translate if translation is available.While not being used currently in FES, browser console let us style messages printed to the console. With the new API, we can also style messages but in a more inline way with API partially inspired by picocolors.
All message is prefixed with
'🌸 p5.js says: 'which itself can be translated, if the prefix is not desired or a different prefix is preferred, aprefixoption can be passed:Extending FES
With the message printing utility, extending FES typically is a matter for addon libraries to decide what they'd like to do with console messages for their own implementation, eg. the
iomodule of p5.js gather its own errors received from trying to load files and print relevant messages with the FES API. There are room for extension within the existing FES features however, such as parameter validation, it would be great to have addon attached methods to also benefit from parameter validation the same way p5.js core functions are.As such an API to extend parameter validation is provided as
p5.extendParameterValidation(). This static method accept an argument of plain object that follows the parameter validation data structure:This adds the expected parameter type for the
circlefunction to the parameter validation system. However, this is hard to author manually so the idea is to prepare tooling, likely in the form of a Rollup plugin (automatically included in the addon template), that will process and generate the necessary code for extending parameter validation. The addon author will need to write inline JSDoc documentation with relevant tag structure and on build, the plugin will parse the JSDoc information, pass it though the same code p5.js use to parse the parameter information and insert necessary code into the final bundle for parameter validation. The plugin part is still an early work in progress and it does not need to be completed for the other parts to be merged.This is a request for comment, please leave any thoughts and review below! There already is a proof of concept implementation and I will file a PR for it soon, do not ask to be assigned