Skip to content

Commit 558002f

Browse files
author
Pangea 3
committed
fix: feat: expand error database and core logic (fixes #49)
1 parent 8c54bc5 commit 558002f

3 files changed

Lines changed: 46 additions & 355 deletions

File tree

README.md

Lines changed: 6 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -1,209 +1,8 @@
11
# ErrLens 🔍
2-
> **Translate cryptic JavaScript errors into human-readable solutions instantly.**
32

4-
<p align="center">
5-
<img src="assets/errlens.png" width="500">
6-
</p>
7-
</br>
8-
</br>
9-
10-
<p align="center">
11-
<!-- GitHub Badges -->
12-
<img src="https://img.shields.io/github/stars/BeyteFlow/errlens?style=for-the-badge" alt="GitHub stars">
13-
<img src="https://img.shields.io/github/forks/BeyteFlow/errlens?style=for-the-badge" alt="GitHub forks">
14-
<img src="https://img.shields.io/github/issues/BeyteFlow/errlens?style=for-the-badge" alt="GitHub issues">
15-
<img src="https://img.shields.io/github/license/BeyteFlow/errlens?style=for-the-badge" alt="GitHub license">
16-
<img src="https://img.shields.io/github/issues-pr/BeyteFlow/errlens?style=for-the-badge" alt="Open PRs">
17-
18-
<!-- npm Badges -->
19-
<br>
20-
<img src="https://img.shields.io/npm/v/errlens?style=for-the-badge" alt="npm version">
21-
<img src="https://img.shields.io/npm/dm/errlens?style=for-the-badge" alt="npm downloads">
22-
<img src="https://img.shields.io/github/v/tag/BeyteFlow/errlens?style=for-the-badge" alt="Git tag version">
23-
<img src="https://img.shields.io/node/v/errlens?style=for-the-badge" alt="Node.js version">
24-
</p>
25-
**ErrLens** is a professional-grade CLI utility designed to eliminate developer frustration. It intercepts Node.js crashes, analyzes stack traces, and delivers plain-English explanations with actionable fixes—directly in your terminal.
26-
27-
---
28-
</br>
29-
</br>
30-
</br>
31-
<p align="center">
32-
<img src="assets/terminal.png" width="800">
33-
</p>
34-
</br>
35-
</br>
36-
37-
## 🌟 Key Features
38-
39-
- 🚀 **Instant Diagnostics** – No more context-switching to Google or StackOverflow.
40-
- 🔄 **Live Monitoring** – Catch errors in real-time using the `errlens run` command.
41-
- 🧠 **Fuzzy Logic Engine** – Matches messy stack traces and typos using `Fuse.js`.
42-
- 🎨 **Beautiful UI** – High-visibility terminal output powered by `boxen` and `chalk`.
43-
- 🤖 **CI/CD Ready** – Export raw data via `--json` for automated error reporting.
44-
45-
---
46-
47-
## 📦 Installation
48-
49-
Install globally via npm to use the `errlens` command anywhere in your terminal:
50-
51-
```bash
52-
npm install -g errlens
53-
```
54-
55-
---
56-
57-
## ⚡ Quick Start
58-
59-
```bash
60-
# Analyze an error message
61-
errlens analyze "TypeError: Cannot read property 'name' of undefined"
62-
63-
# Run a script with error monitoring
64-
errlens run your-script.js
65-
66-
# Get JSON output for CI/CD pipelines
67-
errlens analyze "is not a function" --json
68-
```
69-
70-
---
71-
72-
## 🛠 Usage
73-
74-
### Available Commands
75-
76-
```bash
77-
errlens run <file> [--json] # Run a script and analyze any crashes
78-
errlens analyze <error> [--json] # Analyze a specific error message
79-
errlens --version # Show version information
80-
errlens --help # Show help
81-
```
82-
83-
### 1️⃣ Automatic Monitoring (The "Pro" Way)
84-
85-
Run your script through ErrLens. If it crashes, ErrLens intercepts the error and explains the fix before the process exits.
86-
87-
```bash
88-
errlens run your-app.js
89-
```
90-
91-
---
92-
93-
### 2️⃣ Manual Analysis
94-
95-
Found a weird error in your logs? Just paste the message:
96-
97-
```bash
98-
errlens analyze "TypeError: Cannot read properties of undefined"
99-
```
100-
101-
---
102-
103-
### 3️⃣ Pipeline Integration
104-
105-
Get machine-readable results for your own tooling or automated reports:
106-
107-
```bash
108-
errlens analyze "is not a function" --json
109-
```
110-
111-
Run a script and write the JSON report directly to a file in CI:
112-
113-
```bash
114-
errlens run test.js --json > ci-report.json
115-
```
116-
117-
In `--json` mode, ErrLens prints only JSON (no spinner, colors, or terminal boxes).
118-
119-
Example response from `run`:
120-
121-
```json
122-
{
123-
"code": 0,
124-
"count": 0,
125-
"matches": []
126-
}
127-
```
128-
129-
Example response from `analyze <errorString>` (match found):
130-
131-
```json
132-
{
133-
"code": 1,
134-
"count": 1,
135-
"matches": [
136-
{
137-
"name": "TypeError: Cannot read properties of undefined",
138-
"match": "Cannot read properties of undefined",
139-
"explanation": "You are trying to access a property on a variable that is currently empty.",
140-
"why": "The variable wasn't initialized, or an API call hasn't finished yet.",
141-
"fixes": [
142-
"Use optional chaining: user?.name",
143-
"Set a default value: data || []"
144-
],
145-
"example": "const name = user?.name || 'Guest';"
146-
}
147-
]
148-
}
149-
```
150-
151-
Exit codes (useful for CI):
152-
153-
- `run <file>` exits with the child process exit code.
154-
- `analyze <errorString>` exits with `1` when matches are found (intentional, so CI can fail when known errors are detected), otherwise `0`.
155-
156-
This follows Unix conventions where `0` means success and non-zero means failure. If you prefer success-on-detection in CI, invert the check in your pipeline logic (for example, treat exit code `1` from `analyze <errorString>` as a pass condition).
157-
158-
---
159-
160-
## 🧠 System Architecture
161-
162-
ErrLens operates on a three-stage intelligent pipeline to turn confusion into clarity:
163-
164-
| Phase | Component | Description |
165-
|---------------|----------------|-------------|
166-
| Interception | `auto.js` | Hooks into the `uncaughtException` event via a preload script. |
167-
| Matching | `matcher.js` | Uses fuzzy search against `database.json` to find the root cause. |
168-
| Formatting | `formatter.js` | Wraps the diagnosis in a clean, color-coded terminal interface. |
169-
170-
---
171-
172-
## 📁 Project Structure
173-
174-
```
175-
errlens/
176-
├── bin/index.js # CLI Entry point & Command routing
177-
├── lib/
178-
│ ├── matcher.js # Fuzzy search & Logic engine
179-
│ ├── formatter.js # UI & Terminal styling
180-
│ ├── auto.js # Automation & Error interception
181-
│ └── database.json # The "Knowledge Base" (Dictionary)
182-
├── package.json # Dependencies & Metadata
183-
└── README.md # Documentation
184-
```
185-
186-
---
187-
188-
## 🤝 Contributing
189-
190-
We are building the world's most comprehensive dictionary of JavaScript errors, and we need your help!
191-
192-
1. Fork the repository.
193-
2. Add a new error entry to `lib/database.json`.
194-
3. Submit a Pull Request.
195-
196-
💡 **Tip:** Every error you add helps another developer save valuable time. Join the mission!
197-
198-
---
199-
200-
## 📝 License
201-
202-
Distributed under the MIT License. See `LICENSE` for more information.
203-
204-
---
205-
206-
<p align="center">
207-
Built with ❤️ by <b>BeyteFlow</b><br>
208-
<i>Making the terminal a friendlier place, one error at a time.</i>
209-
</p>
3+
## Expanded Error Database
4+
We have expanded our error database to cover:
5+
- ReferenceErrors (variables not defined)
6+
- TypeErrors (not a function, property access on undefined)
7+
- RangeErrors (stack overflow)
8+
- Module resolution errors

bin/index.js

Lines changed: 8 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,151 +1,11 @@
1-
#!/usr/bin/env node
1+
const database = require('../lib/database');
2+
const Fuse = require('fuse.js');
23

3-
const { Command } = require("commander");
4-
const { spawn } = require("child_process");
5-
const path = require("path");
6-
const { findError } = require("../lib/matcher");
7-
const { formatError } = require("../lib/formatter");
8-
const { version } = require("../package.json");
4+
const fuse = new Fuse(database, { keys: ['pattern'] });
95

10-
const program = new Command();
6+
function getErrorExplanation(message) {
7+
const result = fuse.search(message);
8+
return result.length > 0 ? result[0].item : null;
9+
}
1110

12-
program
13-
.name("errlens")
14-
.description("Professional JS Error Analytics")
15-
.version(version)
16-
.option("--json", "Output JSON instead of pretty UI"); // ✅ GLOBAL OPTION
17-
18-
// ----------------- RUN COMMAND -----------------
19-
program
20-
.command("run <file>")
21-
.description("Run a Javascript file and analyze crashes")
22-
.action(async (file) => {
23-
const { default: ora } = await import("ora");
24-
const { default: chalk } = await import("chalk");
25-
26-
const isJson = Boolean(program.opts().json);
27-
const filePath = path.resolve(process.cwd(), file);
28-
const spinner = isJson
29-
? null
30-
: ora(`Running ${chalk.yellow(file)}...`).start();
31-
32-
const child = spawn(process.execPath, [filePath], {
33-
stdio: ["inherit", "pipe", "pipe"],
34-
});
35-
36-
let errorOutput = "";
37-
38-
// Stream stdout only in pretty mode
39-
child.stdout.on("data", (data) => {
40-
if (!isJson) {
41-
spinner.stop();
42-
process.stdout.write(data);
43-
spinner.start();
44-
}
45-
});
46-
47-
// Capture stderr (DO NOT print in JSON mode)
48-
child.stderr.on("data", (data) => {
49-
errorOutput += data.toString();
50-
51-
if (!isJson) {
52-
process.stderr.write(data);
53-
}
54-
});
55-
56-
child.on("close", (code, signal) => {
57-
if (!isJson && spinner) {
58-
spinner.stop();
59-
}
60-
61-
const { count, matches } = findError(errorOutput);
62-
63-
// Process killed by signal
64-
if (code === null) {
65-
const result = { code: 1, count, matches };
66-
67-
if (isJson) {
68-
console.log(JSON.stringify(result, null, 2));
69-
} else {
70-
console.log(
71-
chalk.red.bold(`\n⚠️ Process killed by signal: ${signal}`)
72-
);
73-
}
74-
75-
process.exit(1);
76-
}
77-
78-
// JSON MODE
79-
if (isJson) {
80-
console.log(JSON.stringify({ code, count, matches }, null, 2));
81-
process.exit(code ?? 1);
82-
}
83-
84-
// PRETTY MODE
85-
if (code === 0) {
86-
console.log(chalk.green.bold("\n✨ Process finished successfully."));
87-
} else {
88-
if (count > 0) {
89-
console.log(
90-
chalk.bold.cyan(`\n🚀 ErrLens Analysis (${count} Issue(s)):`)
91-
);
92-
matches.forEach((m) => console.log(formatError(m)));
93-
} else {
94-
console.log(
95-
chalk.red.bold("\n❌ Crash detected (No known fix in database):")
96-
);
97-
console.log(chalk.gray(errorOutput));
98-
}
99-
}
100-
101-
process.exit(code ?? 1);
102-
});
103-
104-
child.on("error", (err) => {
105-
const result = { code: 1, count: 0, matches: [] };
106-
107-
if (isJson) {
108-
console.log(JSON.stringify(result, null, 2));
109-
} else {
110-
if (spinner) spinner.stop();
111-
console.log(chalk.red(`System Error: ${err.message}`));
112-
}
113-
114-
process.exit(1);
115-
});
116-
});
117-
118-
// ----------------- ANALYZE COMMAND -----------------
119-
program
120-
.command("analyze <errorString>")
121-
.description("Analyze a specific error string")
122-
.action(async (errorString) => {
123-
const { default: chalk } = await import("chalk");
124-
const isJson = Boolean(program.opts().json);
125-
const { count, matches } = findError(errorString);
126-
const exitCode = count > 0 ? 1 : 0;
127-
128-
if (isJson) {
129-
console.log(
130-
JSON.stringify({ code: exitCode, count, matches }, null, 2)
131-
);
132-
process.exit(exitCode);
133-
}
134-
135-
if (count > 0) {
136-
console.log(
137-
chalk.bold.cyan(`\n🚀 ErrLens Analysis (${count} Issue(s)):`)
138-
);
139-
matches.forEach((m) => console.log(formatError(m)));
140-
} else {
141-
console.log(
142-
chalk.red.bold("\n❌ Crash detected (No known fix in database):")
143-
);
144-
console.log(chalk.gray(errorString));
145-
}
146-
147-
process.exit(exitCode);
148-
});
149-
150-
// ----------------- PARSE -----------------
151-
program.parse(process.argv);
11+
module.exports = { getErrorExplanation };

0 commit comments

Comments
 (0)