refactor(onerror): inline error page template as string constant#5868
refactor(onerror): inline error page template as string constant#5868killagu wants to merge 1 commit intoeggjs:nextfrom
Conversation
Inline the mustache error page template as a string constant in src/lib/onerror_page.ts so plugins can be statically bundled by turbopack. Previously the template was read from disk via `import.meta.dirname + readFileSync`, which breaks when modules are embedded in a single bundled chunk. `templatePath` default is now `''`; if set, the custom template file is still loaded via fs, otherwise the inlined constant is used. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe onerror plugin is refactored to support optional custom error templates with a built-in fallback. A new exported constant containing the full HTML error page template is introduced, the default configuration changed to use an empty string instead of a hardcoded file path, and the app initialization updated to conditionally load custom templates or fall back to the built-in template. New subpath exports added to package.json for the template module. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request inlines the error page template into a new TypeScript file, onerror_page.ts, and updates the onerror plugin to use this template by default when templatePath is not configured. This change simplifies the plugin by removing the need to read an external HTML file from the file system in the default case. Feedback was provided to correct minor string formatting issues within the inlined JavaScript template, specifically regarding line number alignment and the display of method locations.
| var u = +o[0], | ||
| m = +o[1] || u, | ||
| h = document.createElement('div'); | ||
| ((h.textContent = Array(m - u + 2).join(' \\n')), |
There was a problem hiding this comment.
There is an extra space before the newline escape sequence in the join call. This will cause line numbers to be joined with a space and a newline (e.g., 1\n 2), which likely breaks the alignment in the error page UI. It should be join('\\n') to correctly join lines with only a newline character.
| ((h.textContent = Array(m - u + 2).join(' \\n')), | |
| ((h.textContent = Array(m - u + 2).join('\\n')), |
| $('#code-drop').setAttribute('class', 'language-' + $language); | ||
| $('#code-drop').innerHTML = $context; | ||
| $('#frame-file').innerHTML = $file; | ||
| $('#frame-method').innerHTML = $method + '' + $lineColumn; |
There was a problem hiding this comment.
The method name and line/column information are joined with an empty string, which will cause them to appear concatenated without a separator (e.g., myFunction10:5). Adding a space would improve the readability of the stack trace view.
| $('#frame-method').innerHTML = $method + '' + $lineColumn; | |
| $('#frame-method').innerHTML = $method + ' ' + $lineColumn; |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
plugins/onerror/src/lib/onerror_page.ts (1)
710-722: Consider limiting sensitive information exposure in error pages.The error page displays
appInfo.baseDirandappInfo.configin non-production environments. While this is useful for debugging, be mindful that this could expose sensitive configuration values if not properly filtered upstream.Based on learnings: "Never expose sensitive configuration values in logs or error messages" - the filtering should be handled in
ErrorViewto ensure sensitive config values are redacted before rendering.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugins/onerror/src/lib/onerror_page.ts` around lines 710 - 722, The error page currently renders raw appInfo.baseDir and appInfo.config which can leak secrets; update ErrorView to sanitize appInfo before rendering by implementing a redaction step (e.g., sanitizeAppInfo or redactConfig) that removes or masks sensitive keys/values from appInfo.config and optionally obfuscates baseDir, then ensure the template rendering in onerror_page.ts uses the sanitizedAppInfo fields (sanitizedAppInfo.config and sanitizedAppInfo.baseDir) instead of the raw appInfo; keep the redaction centralized in ErrorView so all error rendering paths use the sanitized object.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@plugins/onerror/src/lib/onerror_page.ts`:
- Around line 710-722: The error page currently renders raw appInfo.baseDir and
appInfo.config which can leak secrets; update ErrorView to sanitize appInfo
before rendering by implementing a redaction step (e.g., sanitizeAppInfo or
redactConfig) that removes or masks sensitive keys/values from appInfo.config
and optionally obfuscates baseDir, then ensure the template rendering in
onerror_page.ts uses the sanitizedAppInfo fields (sanitizedAppInfo.config and
sanitizedAppInfo.baseDir) instead of the raw appInfo; keep the redaction
centralized in ErrorView so all error rendering paths use the sanitized object.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e249aee1-450d-499f-86e3-1f74048ca748
📒 Files selected for processing (4)
plugins/onerror/package.jsonplugins/onerror/src/app.tsplugins/onerror/src/config/config.default.tsplugins/onerror/src/lib/onerror_page.ts
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Refactors the onerror plugin to inline the error page HTML template as a TypeScript string constant so it can be statically bundled (e.g., by Turbopack), removing the runtime import.meta.dirname + readFileSync dependency.
Changes:
- Adds an inlined
ONERROR_PAGE_TEMPLATEconstant containing the full error page template. - Changes the default
templatePathconfig to''(use built-in template when empty). - Updates the boot logic to use the inlined template unless a custom
templatePathis provided, and exports the new module entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| plugins/onerror/src/lib/onerror_page.ts | Adds the inlined HTML template constant used as the default error page. |
| plugins/onerror/src/config/config.default.ts | Removes default filesystem template path; documents and defaults templatePath to empty string. |
| plugins/onerror/src/app.ts | Switches to inlined template when templatePath is not set; retains file override behavior. |
| plugins/onerror/package.json | Exposes the new lib/onerror_page entry for source and dist builds. |
| } | ||
| } | ||
| function showFrameContext(frame) { | ||
| $frameContext = frame.querySelector('.frame-context'); |
There was a problem hiding this comment.
$frameContext is assigned without var/let/const, which creates an implicit global in non-strict mode (and would throw in strict mode). Declare it as a block-scoped variable (e.g., const $frameContext = ...) to avoid global namespace pollution and potential collisions.
| $frameContext = frame.querySelector('.frame-context'); | |
| const $frameContext = frame.querySelector('.frame-context'); |
| var activeFrame = $('.frame-row.active'); | ||
| if (activeFrame.classList.contains('native-frame')) { | ||
| activeFrame.classList.remove('active'); | ||
| var firstFrame = $$('.frame-row')[0]; | ||
| firstFrame.classList.add('active'); | ||
| showFrameContext(firstFrame); | ||
| } |
There was a problem hiding this comment.
activeFrame can be null if no element matches .frame-row.active (e.g., if frames is empty or no item is marked active), which will cause activeFrame.classList... to throw and break the error page. Add a guard for activeFrame (and also for firstFrame being undefined) before accessing properties/calling showFrameContext.
| displayFirstView(); | ||
| showFrameContext($('.frame-row.active')); | ||
| })(); |
There was a problem hiding this comment.
$('.frame-row.active') may return null, which will cause showFrameContext to throw when it dereferences frame. Consider selecting a safe fallback (e.g., first .frame-row) or short-circuiting when no frame exists, to avoid the error page failing to render in edge cases.
| // logging error | ||
| const config = this.app.config.onerror; | ||
| const viewTemplate = fs.readFileSync(config.templatePath, 'utf8'); | ||
| const viewTemplate = config.templatePath ? fs.readFileSync(config.templatePath, 'utf8') : ONERROR_PAGE_TEMPLATE; |
There was a problem hiding this comment.
Because ONERROR_PAGE_TEMPLATE is imported at module load time, the runtime must parse/allocate the large inlined template even when users provide templatePath (and the built-in template is never used). If startup cost matters, consider deferring loading the default template (e.g., via a dynamic import or a getter function that’s only invoked when templatePath is falsy). Tradeoff: dynamic import adds a small async boundary/complexity but avoids paying the parse cost in override scenarios.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #5868 +/- ##
=======================================
Coverage 86.00% 86.00%
=======================================
Files 667 668 +1
Lines 18945 18946 +1
Branches 3652 3653 +1
=======================================
+ Hits 16294 16295 +1
Misses 2297 2297
Partials 354 354 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| onerror: { | ||
| errorPageUrl: '', | ||
| appErrorFilter: undefined, | ||
| templatePath: path.join(import.meta.dirname, '../lib/onerror_page.mustache.html'), |
There was a problem hiding this comment.
should delete onerror_page.mustache.html file too
Summary
Inlines the 1336-line error page HTML template into `plugins/onerror/src/lib/onerror_page.ts` as a string constant. Removes the runtime `readFileSync` + `import.meta.dirname` lookup, sets the `templatePath` config default to an empty string, and updates `app.ts` to import the inlined constant.
Why
This is batch 1, part of a 19-PR split of #5863 (the egg-bundler PR). #5863 is kept open as a tracking reference. This PR is independent of the other batch-1 PRs.
Turbopack (and any static bundler) cannot follow `import.meta.dirname + readFileSync` to a template file, so the file would be missing in a bundled deployment. Inlining the HTML as a string constant makes the plugin statically bundleable.
This is a pure refactor — runtime behavior is identical, the user-supplied `templatePath` config still overrides the default.
Test plan
Stack context
Other batch-1 PRs (independent, can land in any order):
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Chores