Conversation
Introduce a new CLI subcommand (errlens run <file>) that spawns a Node child process, streams logs in real-time, captures stderr for analysis, and reports known issues or raw crash output. Add lib/injector.js to enable automatic runtime analysis for uncaught exceptions and unhandled promise rejections when injected into a project. Revamp matcher.findError to return {count,matches} and switch from fuzzy search to deterministic substring matching with specificity sorting and deduplication. Update auto.js to use the new matcher API and improve console output. Improve formatter styling and layout (fixed width, title tweak, margin change) and normalize fixes arrays in database.json; also add a couple of new syntax-related entries. Minor CLI description/version update and general UX/error reporting enhancements.
📝 WalkthroughWalkthroughReplaces the CLI with a new Changes
Sequence DiagramsequenceDiagram
participant User as User
participant CLI as bin/index.js
participant Child as Node Child Process
participant Injector as lib/injector.js
participant Matcher as lib/matcher.js
participant Formatter as lib/formatter.js
participant Console as Console Output
User->>CLI: run <file>
CLI->>Child: spawn node <file>
Child->>Child: execute script
par Stdout
Child-->>CLI: stdout stream
CLI->>Console: print logs (streamed)
end
par Crash Path
Child-->>Injector: uncaught exception / rejection (stack/message)
Injector->>Matcher: findError(stack)
Matcher-->>Injector: { count, matches }
alt matches > 0
Injector->>Formatter: formatError(match)
Formatter-->>Console: colored formatted results
else no matches
Injector-->>Console: raw error (red)
end
end
Child-->>CLI: exit code
alt code == 0
CLI->>Console: success message
else
CLI->>Console: analyzed or raw crash output
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 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.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/index.js`:
- Around line 63-65: The child.on("error") handler currently only calls
spinner.fail(chalk.red(...)) and leaves the CLI running; update the handler in
bin/index.js so after spinner.fail(...) it sets a non-zero exit (e.g.
process.exitCode = 1 or call process.exit(1)) to fail fast on spawn/system
errors and then return/exit to stop further processing; target the
child.on("error", (err) => { ... }) block and ensure the error message from
err.message is preserved when you set the exit.
- Around line 44-61: In the child.on("close", (code) => ...) handler, explicitly
accept the signal parameter (use (code, signal) => ...) and treat code === null
as a signal-based termination: stop the spinner, log a clear message that the
child was killed by the given signal (include the signal variable), and exit
with a non-zero status instead of passing null to process.exit; replace the
final process.exit(code) with process.exit(code ?? 1) (or process.exit(1) when
code is null) so signal-driven exits are not treated as successful; keep the
existing errorOutput/findError/formatError logic unchanged.
- Around line 25-27: Replace the hard-coded "node" in the spawn call with
process.execPath and pass an explicit stdio option to inherit stdin while piping
stdout/stderr (e.g. spawn(process.execPath, [filePath], { stdio: ['inherit',
'pipe', 'pipe'] })), and attach/adjust the spawn error handler for the child
process (the variable child) so that on error it logs the failure and calls
process.exit(1) to exit with a non-zero code.
In `@lib/auto.js`:
- Around line 6-7: The call to findError(err.message) assumes err is a standard
Error and misses non-Error throws; change it to compute a null-safe search
string (e.g., let msg = (err && err.message) ? err.message : String(err)) and
pass that msg into findError so findError receives a usable string for both
Error objects and primitive/non-standard throws; update any surrounding
references to use this message variable instead of err.message (look for
findError and err.message in lib/auto.js).
In `@lib/injector.js`:
- Line 12: The crash-handler assumes err is an object with stack/message; guard
against null/undefined by normalizing the thrown value before calling findError:
compute a safe string (e.g., check err !== null && typeof err === 'object' ?
(err.stack || err.message) : String(err) or a default like 'unknown error') and
pass that safe string into findError; update the use-sites (the occurrence
calling findError and the later access at line 29) so both read from the
normalized value instead of accessing err.stack or err.message directly.
In `@lib/matcher.js`:
- Around line 4-7: The code calls input.toLowerCase() without ensuring input is
a string; add a type guard before computing lowerInput (the call site where
lowerInput = input.toLowerCase()) to handle non-string truthy values safely —
e.g., check typeof input === 'string' and only proceed, otherwise return the
empty result ({ count: 0, matches: [] }) or coerce via String(input) if you want
to accept non-string primitives; update the logic around lowerInput to use that
guard so toLowerCase is never invoked on non-string values.
|
@copilot In Verify each finding against the current code and only fix it if needed. In Verify each finding against the current code and only fix it if needed. In In Verify each finding against the current code and only fix it if needed. In Verify each finding against the current code and only fix it if needed. In |
…rs, add type guard in matcher Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com>
Harden spawn, signal handling, and null-error guards across run command and runtime hooks
There was a problem hiding this comment.
🧹 Nitpick comments (4)
bin/index.js (1)
60-60: Optional: Same linter hint as other files on forEach callback.Consistent with
lib/auto.jsandlib/injector.js- use block body if you want to silence the Biome warning.♻️ Optional fix
- matches.forEach(m => console.log(formatError(m))); + matches.forEach(m => { console.log(formatError(m)); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@bin/index.js` at line 60, The forEach callback uses a concise arrow body which triggers the linter warning elsewhere; update the matches.forEach usage (the matches.forEach callback that calls formatError) to use a block body arrow function instead (e.g., matches.forEach(m => { console.log(formatError(m)); }) ) so it matches the style used in lib/auto.js and lib/injector.js and silences the Biome warning while keeping the same behavior.lib/auto.js (2)
6-8: Null-safe extraction implemented, but consider including stack trace.The guard correctly handles non-Error throws. However, unlike
lib/injector.jswhich useserr.stack || err.message, this file only useserr.message. Stack traces often contain additional context that improves matching accuracy.♻️ Optional: Include stack trace for richer analysis
process.on("uncaughtException", (err) => { - // Use the message for the search, guard against non-Error throws - const msg = (err && err.message) ? err.message : String(err); + // Use the stack trace for the search (includes message), guard against non-Error throws + const msg = (err && typeof err === "object") ? (err.stack || err.message) : String(err); const { count, matches } = findError(msg);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/auto.js` around lines 6 - 8, The extraction of the error text for findError in lib/auto.js only uses err.message (const msg = ...), so update the logic to prefer the stack when available (e.g., use err.stack || err.message or concatenate both) before passing to findError; modify the msg assignment in the same block where const msg is defined so that findError(msg) receives the richer text for better matching.
10-17: Output flow is correct; static analysis hint is low-priority.The logic properly branches on match count. The Biome warning about
forEachcallback return value is technically correct (arrow function implicitly returnsconsole.log's undefined), but has no functional impact. If you want to silence the linter:♻️ Optional: Use block body to satisfy linter
- matches.forEach(match => console.log(formatError(match))); + matches.forEach(match => { console.log(formatError(match)); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/auto.js` around lines 10 - 17, The linter warns about the implicit return of the arrow callback in the forEach call in the auto.js block that logs matches; change the arrow callback in matches.forEach(match => console.log(formatError(match))) to use a block body (e.g., matches.forEach(match => { console.log(formatError(match)); })) or replace with a for...of loop to explicitly avoid returning a value from the callback in the function that prints detected issues.lib/injector.js (1)
17-17: Optional: Silence linter warnings on forEach callbacks.Same low-priority issue as
lib/auto.js- the arrow functions implicitly returnconsole.log's undefined. No functional impact, but block bodies would satisfy the linter.♻️ Optional fix for both lines
- matches.forEach(match => console.log(formatError(match))); + matches.forEach(match => { console.log(formatError(match)); });Also applies to: 35-35
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/injector.js` at line 17, The linter warns because the forEach callbacks use concise arrow bodies that implicitly return console.log's undefined; update the callbacks in lib/injector.js (the matches.forEach(...) calls that invoke formatError) to use block arrow bodies so they explicitly execute console.log without an implicit return (e.g., replace the concise arrow with a brace-enclosed block that calls console.log(formatError(match));); do the same for the other occurrence on the file (around the second matches.forEach).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@bin/index.js`:
- Line 60: The forEach callback uses a concise arrow body which triggers the
linter warning elsewhere; update the matches.forEach usage (the matches.forEach
callback that calls formatError) to use a block body arrow function instead
(e.g., matches.forEach(m => { console.log(formatError(m)); }) ) so it matches
the style used in lib/auto.js and lib/injector.js and silences the Biome warning
while keeping the same behavior.
In `@lib/auto.js`:
- Around line 6-8: The extraction of the error text for findError in lib/auto.js
only uses err.message (const msg = ...), so update the logic to prefer the stack
when available (e.g., use err.stack || err.message or concatenate both) before
passing to findError; modify the msg assignment in the same block where const
msg is defined so that findError(msg) receives the richer text for better
matching.
- Around line 10-17: The linter warns about the implicit return of the arrow
callback in the forEach call in the auto.js block that logs matches; change the
arrow callback in matches.forEach(match => console.log(formatError(match))) to
use a block body (e.g., matches.forEach(match => {
console.log(formatError(match)); })) or replace with a for...of loop to
explicitly avoid returning a value from the callback in the function that prints
detected issues.
In `@lib/injector.js`:
- Line 17: The linter warns because the forEach callbacks use concise arrow
bodies that implicitly return console.log's undefined; update the callbacks in
lib/injector.js (the matches.forEach(...) calls that invoke formatError) to use
block arrow bodies so they explicitly execute console.log without an implicit
return (e.g., replace the concise arrow with a brace-enclosed block that calls
console.log(formatError(match));); do the same for the other occurrence on the
file (around the second matches.forEach).
Introduce a new CLI subcommand (errlens run ) that spawns a Node child process, streams logs in real-time, captures stderr for analysis, and reports known issues or raw crash output. Add lib/injector.js to enable automatic runtime analysis for uncaught exceptions and unhandled promise rejections when injected into a project. Revamp matcher.findError to return {count,matches} and switch from fuzzy search to deterministic substring matching with specificity sorting and deduplication. Update auto.js to use the new matcher API and improve console output. Improve formatter styling and layout (fixed width, title tweak, margin change) and normalize fixes arrays in database.json; also add a couple of new syntax-related entries. Minor CLI description/version update and general UX/error reporting enhancements.
🚀 BΞYTΞFLʘW | Pull Request Protocol
PR Type: (Choose one:
feat|fix|refactor|docs|perf)Issue Link: Fixes #
📝 System Summary
Provide a concise brief of the changes introduced to the stream.
🛠️ Technical Changes
.........🧪 Quality Assurance (QA)
npm run buildexecuted without errors.🖼️ Visual Evidence
If this PR affects the UI, drop a screenshot or GIF below:
📡 Developer Authorization
Authorized by: @naheel0
Timestamp: {{ 1/3/2026 }}
Summary by CodeRabbit
New Features
Behavior Changes