资讯动态

深入解析 p5.js 友好错误系统(FES):从内部机制到贡献指南

发布时间:2026/9/12 16:48:11 来源:尧图企业网站定制
深入解析 p5.js 友好错误系统FES从内部机制到贡献指南【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.jsoutput_articlep5.js Friendly Error SystemFES深度解析核心函数、调用链与开发贡献指南p5.js 的友好错误系统Friendly Error System简称 FES是一套内置于库中的错误诊断与提示机制它以 p5.js says:为前缀在浏览器原生报错之外补充更易读、可操作的提示信息。本文以 contributor_docs/fes_contribution_guide.md 为核心骨架结合仓库源码逐层拆解 FES 的架构、核心函数、运行流程与已知局限帮助读者理解其内部工作原理并掌握为 p5.js 贡献 FES 代码的方法。FES 是什么——p5.js 的友好报错体系在浏览器控制台中运行 p5.js 草图时你可能会看到以 p5.js says:开头的消息它们补充甚至替代了浏览器默认的错误提示。这些消息正是由 p5.js 的 Friendly Error System 生成的。FES 位于源码 src/friendly_errors/ 目录它汇集了多个负责生成不同类型友好错误消息的函数。这些函数从各种位置收集错误信息包括文件加载错误与浏览器自动播放autoplay策略导致的错误处理库内部函数调用时的参数检查p5.js 贡献者实现的其他自定义错误处理逻辑。FES 生成友好错误的主要入口函数有四个详见 fes_core.js 的文件头注释函数作用p5._friendlyError()格式化并通过_report()打印输入消息为友好错误p5._validateParameters()校验接收到的输入值是否为错误类型或缺少值p5._friendlyFileLoadError()引导用户处理与文件加载函数相关的错误p5._friendlyAutoplayError()引导用户处理与浏览器自动播放策略相关的错误注原文档在正文中以文字形式描述了 FES 各文件的功能关系图该图对应仓库中的contributor_docs/images/fes.svg由于本文聚焦文字化的架构讲解读者可直接在仓库中查看该 SVG 文件了解函数间的连接关系。FES 各文件的分工如下路径均为相对仓库根目录src/friendly_errors/fes_core.js包含_report()、_friendlyError()、_friendlyAutoplayError()以及其他用于格式化和测试友好错误的辅助函数src/friendly_errors/param_validator.js包含_validateParameters()及其他参数校验辅助函数src/friendly_errors/browser_errors.js包含一份浏览器错误列表这些错误会通过 FES 的全局错误类fes.globalErrors生成友好提示src/friendly_errors/stacktrace.js包含用于解析错误堆栈的代码从 stacktrace.js 项目借鉴。从源码 src/friendly_errors/index.js 可以看到FES 由四个 addon 组成通过p5.registerAddon()注册进 p5 实例import fesCore from ./fes_core; import validateParams from ./param_validator.js; import sketchVerifier from ./sketch_verifier.js; import fes from ./fes; export default function (p5) { p5.registerAddon(fes); p5.registerAddon(fesCore); p5.registerAddon(validateParams); p5.registerAddon(sketchVerifier); }这意味着 FES 以插件addon形式挂载p5.FES、p5._friendlyError等静态方法只有在 FES 模块加载后才会被赋予真实实现未加载时 src/core/main.js 中以空函数 stub 兜底。_report()所有友好错误的最终出口描述_report()是直接向控制台打印错误辅助消息输出的主要函数。所有友好错误消息最终都会经由它输出。关键设计如果设置了p5._fesLogger例如运行测试时它会替代console.log被使用。这在通过 Mocha 运行单元测试时非常有用——_fesLogger会让_report将错误消息作为字符串传递给 Mocha并与断言字符串进行比较。语法_report(message); _report(message, func); _report(message, func, color);参数param {String} message Message to be printed param {String} [func] Name of function param {Number|String} [color] CSS color code[func]输入用于在错误消息末尾追加指向 p5.js 参考文档的链接[color]输入用于设置错误消息的颜色属性在当前版本的友好错误消息中并未实际使用。源码实现在 fes_core.js 中p5._report的实现如下为便于阅读已省略 JSDoc 注释p5._report (message, func) { // Add a link to the reference docs of func at the end of the message message mapToReference(message, func); FES.log${message}(); };它调用mapToReference()将func转换为对应的 p5.js 参考文档链接例如arc会得到https://p5js.org/reference/p5/arc再通过 fes.js 中FES.log模板函数输出。FES.log会默认加上 p5.js says:前缀并支持多语言翻译TL.tl与样式字符串%c。位置src/friendly_errors/fes_core.js_friendlyError()通用的友好错误生成入口描述_friendlyError()创建并打印一条友好错误消息。任何 p5 函数都可以调用它来提供友好错误提示。它在 fes_core.js 中的实现非常简洁p5._friendlyError function (message, func) { if (p5.disableFriendlyErrors) return; p5._report(message, func); };可以看到它先检查p5.disableFriendlyErrors开关再委托给_report()。其调用链为_friendlyError _report mapToReference FES.log控制台输出带 p5.js says: 前缀_friendlyFileLoadError()文件加载错误专项指引描述_friendlyFileLoadError()为文件加载失败提供专项指引。它在以下 p5 函数内部被调用src/image/loading_displaying.js 中的loadImage()src/io/files.js 中的loadFont()、loadTable()、loadJSON()、loadStrings()、loadXML()、loadBytes()从源码注释可见loadBytes()对应错误类型 1、loadTable()对应 2、loadJSON()对应 3、loadStrings()对应 5、loadXML()对应 6loadImage()对应类型 0 与 8。其调用序列如下_friendlyFileLoadError _report语法_friendlyFileLoadError(errorType, filePath);参数param {Number} errorType Number of file load error type param {String} filePath Path to file caused the errorerrorType对应文件加载错误的特定类型其枚举定义在core/friendly_errors/file_errors.js仓库中对应 src/friendly_errors/ 目录。p5.js 将文件加载错误划分为多种不同场景以便针对不同错误情况给出精确、信息量充足的提示。例如当字体文件中的数据无法读取时与尝试加载过大文件时会显示不同的错误。示例文件加载错误示例——缺失字体文件/// missing font file let myFont; function preload() { myFont loadFont(assets/OpenSans-Regular.ttf); } function setup() { fill(#ED225D); textFont(myFont); textSize(36); text(p5*js, 10, 50); } function draw() {}FES 会在控制台生成以下消息叠加在浏览器原生 unsupported 错误之上 p5.js says: It looks like there was a problem loading your font. Try checking if the file path (assets/OpenSans-Regular.ttf) is correct, hosting the file online, or running a local server. More info: https://github.com/processing/p5.js/wiki/Local-server位置src/friendly_errors/fes_core.js_friendlyFileLoadError相关实现所在目录为src/friendly_errors/_friendlyAutoplayError()浏览器自动播放策略提示描述_friendlyAutoplayError()在播放媒体例如视频出错时被内部调用这种错误通常源于浏览器的自动播放策略。它调用translator()使用键fes.autoplay生成并打印友好错误消息。所有可用的翻译键都可以在 translations/en/translation.json 中查看。位置src/friendly_errors/fes_core.js_validateParameters()参数校验的核心引擎描述_validateParameters()通过将输入参数与函数内联文档生成的信息进行匹配来运行参数校验——它检查函数调用是否包含正确数量的参数以及正确类型的参数。它调用translator()使用键fes.friendlyParamError.*生成并打印友好错误消息翻译键参见 translations/en/translation.json。该函数可通过以下两种方式调用p5._validateParameters(FUNCT_NAME, ARGUMENTS); p5.prototype._validateParameters(FUNCT_NAME, ARGUMENTS);推荐在一般情况下使用静态版本p5._validateParameters。p5.prototype._validateParameters(FUNCT_NAME, ARGUMENTS)主要保留用于调试和单元测试。在仓库中_validateParameters的实现位于 src/friendly_errors/param_validator.js它内部维护了一张基于 Zod schema 的schemaMap含Any、Array、Boolean、Function、Integer、Number、Object、String等基础类型并通过docs/parameterData.json即 docs/parameterData.json中的参数元数据与运行时常量表constantsMap来自 src/core/constants.js来匹配用户实参。_validateParameters()被内置于以下函数模块中列表依据原文档并结合仓库结构整理src/accessibility/outputs.jsaccessibility/outputssrc/color/creating_reading.jscolor/creating_readingsrc/color/setting.jscolor/settingsrc/core/environment.js、src/core/rendering.js、src/core/transform.jscore/environment、core/rendering、core/transformsrc/shape/2d_primitives.js、src/shape/attributes.js、src/shape/curves.js、src/shape/vertex.jscore/shape/2d_primitives、attributes、curves、vertexsrc/data/ 中的p5.TypedDictsrc/dom/dom.jsdom/domsrc/events/acceleration.js、src/events/keyboard.jsevents/acceleration、events/keyboardsrc/image/image.js、src/image/loading_displaying.js、src/image/p5.Image.js、src/image/pixels.jsimage/image、loading_displaying、p5.Image、pixelsrc/io/files.jsio/filessrc/math/calculation.js、src/math/random.jsmath/calculation、math/randomtypography/attributes、typography/loading_displaying对应 src/type/ 相关文件src/utilities/ 中的 string_functionssrc/webgl/3d_primitives.js、src/webgl/interaction.js、src/webgl/light.js、src/webgl/loading.js、src/webgl/material.js、src/webgl/p5.Camera.jswebgl/3d_primitives、interaction、light、loading、material、p5.Camera从_validateParameters出发的调用链大致如下validateParameters buildArgTypeCache addType lookupParamDoc scoreOverload testParamTypes testParamType getOverloadErrors _friendlyParamError ValidationError report friendlyWelcome语法_validateParameters(func, args);参数param {String} func Name of the function being called param {Array} args User input arguments示例缺少参数示例arc(1, 1, 10.5, 10);FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 13] arc() was expecting at least 6 arguments, but received only 4. (https://p5js.org/reference/p5/arc)类型不匹配示例arc(1, ,1, 10.5, 10, 0, Math.PI);FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 14] arc() was expecting Number for the first parameter, received string instead. (https://p5js.org/reference/p5/arc)位置src/friendly_errors/param_validator.jsfesErrorMonitor()全局错误监听与拼写检查描述fesErrorMonitor()监听浏览器错误消息以推测错误的来源并向用户提供额外指引。这包括堆栈跟踪stack trace——即程序中一系列按顺序调用的函数列表直到抛出错误的位置。堆栈跟踪对于判断错误是库内部错误还是由用户直接调用引起的错误非常有用。它调用translator()使用键fes.globalErrors.*生成并打印友好错误消息翻译键参见 translations/en/translation.json。以下是经由fesErrorMonitor()生成的错误消息的完整列表使用键fes.globalErrors.syntax.*、fes.globalErrors.reference.*、fes.globalErrors.type.*的友好错误消息通过processStack()生成的内部库错误消息使用键fes.wrongPreload、fes.libraryError通过printFriendlyStack()生成的堆栈跟踪消息使用键fes.globalErrors.stackTop、fes.globalErrors.stackSubseq通过handleMisspelling()生成的拼写检查消息源自引用错误使用键fes.misspelling。_fesErrorMonitor()会在window上的error事件与未处理的 Promise 拒绝unhandledrejection事件发生时自动触发。不过它也可以在 catch 块中手动调用try { someCode(); } catch (err) { p5._fesErrorMonitor(err); }该函数目前支持ReferenceError、SyntaxError和TypeError的子集。支持的错误完整列表见 src/friendly_errors/browser_errors.js。在该文件中每种浏览器错误都有对应的消息模式与类型分类例如ReferenceError的NOTDEFINEDis not defined / Safari 的 Cant find variable与CANNOTACCESSCannot access ... before initializationSyntaxError的INVALIDTOKEN、UNEXPECTEDTOKEN、REDECLAREDVARIABLE、MISSINGINITIALIZER、BADRETURNORYIELDTypeError的NOTFUNC、READNULL、READUDEFINED、CONSTASSIGN。同一错误在不同浏览器的措辞不同因此该表按浏览器browser: Chrome | Firefox | Safari | all分别维护匹配模式。_fesErrorMonitor的调用链大致如下_fesErrorMonitor processStack printFriendlyError (if type of error is ReferenceError) _handleMisspelling computeEditDistance _report _report printFriendlyStack (if type of error is SyntaxError, TypeError, etc) _report printFriendlyStack语法fesErrorMonitor(event);参数param {*} e Error event示例内部错误示例 1——在preload()中调用了background()function preload() { // error in background() due to it being called in // preload background(200); }FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 8] An error with message Cannot read properties of undefined (reading background) occurred inside the p5js library when background was called. If not stated otherwise, it might be due to background being called from preload. Nothing besides load calls (loadImage, loadJSON, loadFont, loadStrings, etc.) should be inside the preload function. (https://p5js.org/reference/p5/preload)内部错误示例 2——mouseClicked()缺少回调参数function setup() { cnv createCanvas(200, 200); cnv.mouseClicked(); }FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 12] An error with message Cannot read properties of undefined (reading bind) occurred inside the p5js library when mouseClicked was called. If not stated otherwise, it might be an issue with the arguments passed to mouseClicked. (https://p5js.org/reference/p5/mouseClicked)作用域错误示例——在draw()中访问了setup()内的局部变量function setup() { let b 1; } function draw() { b 1; }FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 5] b is not defined in the current scope. If you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). More info: https://p5js.org/examples/data-variable-scope.html拼写错误示例——把color()误写为xolor()function setup() { xolor(1, 2, 3); }FES 会在控制台生成以下消息 p5.js says: [sketch.js, line 2] It seems that you may have accidentally written xolor instead of color. Please correct it to color if you wish to use the function from p5.js. (https://p5js.org/reference/p5/color)源码级原理拼写检查如何工作拼写检查依赖 fes_core.js 中的handleMisspelling()与computeEditDistance()misusedAtTopLevelCode是一个惰性初始化的 p5 公开符号列表函数/常量/变量按名称长度降序排序以确保优先报告最具体的匹配例如误用HALF_PI时提示HALF_PI而非PIcomputeEditDistance()使用 Wagner–Fischer 算法计算两个字符串间的 Levenshtein 距离编辑距离阈值EDIT_DIST_THRESHOLD 2只有当最近匹配的距离不超过该阈值且小于等于符号自身长度时才判定为拼写错误只有一个最接近匹配时消息附带参考文档链接有多个匹配时逐行列出每个建议函数名后带()。位置src/friendly_errors/fes_core.jscheckForUserDefinedFunctions()用户自定义函数的大小写检查描述检查是否有用户自定义函数setup()、draw()、mouseMoved()等被以大小写错误的方式使用。它调用translator()使用键fes.checkUserDefinedFns生成并打印友好错误消息翻译键参见 translations/en/translation.json。在源码中该函数通过window.addEventListener(load, checkForUserDefinedFunctions, false)在页面加载时自动执行同时在实例模式下创建 p5 实例时src/core/main.js 的构造函数中也会调用p5._checkForUserDefinedFunctions(this)来检测setup、draw等的大小写错误。语法checkForUserDefinedFunctions(context);参数param {*} context Current default context. Set to window in global mode and to a p5 instance in instance mode示例function preload() { loadImage(myimage.png); }注意此处的误拼为preLoad——示例旨在演示 p5.js 2.0 之前的旧行为。在当前仓库中preload()已被移除p5 2.0 建议在setup()中使用async/await或回调加载资源若用户仍定义了preloadfes_core.js 会打印迁移提示。FES 会在控制台生成以下消息 p5.js says: It seems that you may have accidentally written preLoad instead of preload. Please correct it if its not intentional. (https://p5js.org/reference/p5/preload)位置src/friendly_errors/fes_core.jshelpForMisusedAtTopLevelCode()顶层代码误用检测描述helpForMisusedAtTopLevelCode()由fes_core.js在 window 加载时调用用于检查是否有 p5.js 函数在setup()或draw()之外被使用。它调用translator()使用键fes.misusedTopLevel生成并打印友好错误消息翻译键参见 translations/en/translation.json。从源码看该函数会遍历misusedAtTopLevelCode列表用\W?{symbol}\W正则匹配错误消息文本一旦命中即提示用户将 p5 符号移入setup()并附上 FAQ 链接。由于不同浏览器对同一错误的措辞不同例如 Chrome 的Uncaught ReferenceError: PI is not defined与 Firefox 的ReferenceError: PI is undefined该实现刻意采用宽松的符号名匹配源码注释中也提示这可能在少数情况下产生误报。参数param {*} err Error event param {Boolean} log false位置src/friendly_errors/fes_core.js开发笔记已知局限与未来方向误报False Positive与漏报False Negative在 FES 中你会遇到两类错误误报False Positive像假警报。FES 警告你有一个错误但你的代码实际上是正确的漏报False Negative像漏掉了错误。你的代码中存在错误但 FES 没有向你发出警报。识别并修复这两类错误非常重要因为它们能节省调试时间、减少困惑并让修复真正的问题变得更容易。在某些不理想的情况下错误处理的设计可能需要二选一消除误报或消除漏报。如果必须选择通常更倾向于消除误报——这样可以避免生成可能分散或误导用户注意力的错误警告。与fes.GlobalErrors相关的局限FES 只能检测使用const或var声明的被覆盖全局变量使用let声明的变量无法被检测到。这一局限源于let处理变量实例化的特殊方式目前无法解决。fesErrorMonitor()描述的功能目前仅在 Web Editor 中或运行在本地服务器上时才有效。FES 的性能问题默认情况下FES 在 p5.js 中启用在p5.min.js中禁用以防止 FES 函数拖慢进程。错误检查系统可能显著降低代码运行速度在某些情况下最高可达约 10 倍。可以在草图顶部用一行代码禁用 FESp5.disableFriendlyErrors true; // disables FES function setup() { // Do setup stuff } function draw() { // Do drawing stuff }在 src/core/main.js 的disableFriendlyErrors属性文档中说明了同样的用法并指出禁用后circle(50, 50)这类缺参调用将静默失败而不显示友好错误。请注意禁用 FES 会关闭某些已知影响性能的功能例如参数检查。但那些不影响性能的友好错误消息仍然会启用包括文件加载失败时的详细错误消息以及在全局空间中试图覆盖 p5.js 函数时的警告。从源码可以确认这个开关的实际作用范围fes_core.js 中_friendlyError()、checkForUserDefinedFunctions()、fesErrorMonitor()的入口都带有if (p5.disableFriendlyErrors) return;守卫param_validator.js 的参数校验同样受该开关控制而 src/webgl/p5.Renderer3D.js 与 src/math/p5.Vector.js 也会查询该开关。此外src/strands/p5.strands.js 在内部执行转换时会临时保存并恢复p5.disableFriendlyErrors的值以避免 FES 干扰转换流程。未来工作方向原文档列出了以下未来改进方向解耦 FESDecouple FES消除误报案例识别漏报案例增加更多单元测试以提升测试覆盖率更直观、清晰、可翻译的消息友好错误的国际化讨论可参考社区整理的 FES i18n 资料识别更多常见错误类型并用 FES 泛化处理例如bezierVertex()、quadraticVertex()中必需对象未初始化的情况检查nf()、nfc()、nfp()、nfs()的 Number 参数是否为正数。结论本文以 contributor_docs/fes_contribution_guide.md 为骨架梳理了 src/friendly_errors/ 目录的组织结构与每个核心函数的用途。FES 的核心入口函数——_report()、_friendlyError()、_friendlyFileLoadError()、_friendlyAutoplayError()、_validateParameters()、fesErrorMonitor()、checkForUserDefinedFunctions()、helpForMisusedAtTopLevelCode()——分别承担控制台输出、通用错误生成、文件加载错误、自动播放错误、参数校验、全局错误监听、大小写检查与顶层代码误用检测等职责。同时我们也结合贡献者笔记了解了 FES 的已知局限误报/漏报权衡、let声明的全局变量无法检测、错误监听依赖本地服务器与性能代价可通过p5.disableFriendlyErrors true关闭以及未来在解耦、测试覆盖与消息国际化方面的改进方向。对于希望为 p5.js 贡献 FES 代码的开发者而言这些内容既是源码导航图也是参与改进的起点——例如从消除误报、补充单元测试这类明确可执行的方向入手。 /output_article【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价