errorxplain 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # errorxplain
2
+
3
+ Intelligent Error Explainer CLI & Middleware for backend developers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g errorxplain
9
+ ```
10
+
11
+ ## CLI Usage
12
+
13
+ ```bash
14
+ errorxplain watch ./logs
15
+ errorxplain explain "ECONNREFUSED 127.0.0.1:5432"
16
+ ```
17
+
18
+ ## Middleware Usage (Express)
19
+
20
+ ```js
21
+ import express from "express";
22
+ import { errorExplainer } from "errorxplain/lib/middleware.js";
23
+
24
+ const app = express();
25
+ app.use(errorExplainer());
26
+ ```
27
+
28
+ Author: Shashank Neupane
package/bin/errx.js ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { watchLogs, explainError } from "../lib/engine.js";
3
+
4
+ const args = process.argv.slice(2);
5
+
6
+ if (!args.length) {
7
+ console.log("Usage: errorxplain [watch|explain] <path|error>");
8
+ process.exit(0);
9
+ }
10
+
11
+ const command = args[0];
12
+
13
+ if (command === "watch") {
14
+ const logPath = args[1] || "./logs";
15
+ watchLogs(logPath);
16
+ } else if (command === "explain") {
17
+ const errorText = args.slice(1).join(" ");
18
+ const explanation = explainError(errorText);
19
+ console.log("\nError Explanation:\n", explanation, "\n");
20
+ } else {
21
+ console.log("Invalid command. Usage: errorxplain [watch|explain] <path|error>");
22
+ }
package/lib/engine.js ADDED
@@ -0,0 +1,88 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ let rules = [];
5
+
6
+ // Path to JSON rules
7
+ const rulesFile = path.resolve("./lib/rules/rules.json");
8
+
9
+ // Track last read position for each log file
10
+ const filePositions = {};
11
+
12
+ // Load rules from JSON and convert patterns to RegExp
13
+ function loadRules() {
14
+ try {
15
+ const rawRules = JSON.parse(fs.readFileSync(rulesFile, "utf8"));
16
+ rules = rawRules.map(r => ({ ...r, pattern: new RegExp(r.pattern) }));
17
+ console.log(`Loaded ${rules.length} error rules`);
18
+ } catch (err) {
19
+ console.error("Failed to load rules.json:", err.message);
20
+ }
21
+ }
22
+
23
+ // Initial load
24
+ loadRules();
25
+
26
+ // Hot-reload rules whenever rules.json changes
27
+ fs.watchFile(rulesFile, { interval: 1000 }, () => {
28
+ console.log("Detected change in rules.json, reloading rules...");
29
+ loadRules();
30
+ });
31
+
32
+ // Explain a single error
33
+ export function explainError(errorText) {
34
+ const match = rules.find(r => r.pattern.test(errorText));
35
+ if (match) return match;
36
+ return { meaning: "Unknown error", fix: "Search documentation or logs" };
37
+ }
38
+
39
+ // Watch logs in real-time
40
+ export function watchLogs(logDir) {
41
+ // Ensure folder exists
42
+ if (!fs.existsSync(logDir)) {
43
+ fs.mkdirSync(logDir, { recursive: true });
44
+ console.log(`Created missing logs folder at ${logDir}`);
45
+ }
46
+
47
+ console.log(`Watching logs at ${logDir}...`);
48
+
49
+ fs.watch(logDir, (eventType, filename) => {
50
+ if (!filename) return;
51
+
52
+ const filePath = path.join(logDir, filename);
53
+
54
+ // Initialize last position
55
+ if (!filePositions[filePath]) filePositions[filePath] = 0;
56
+
57
+ fs.stat(filePath, (err, stats) => {
58
+ if (err) return console.error("Stat error:", err.message);
59
+
60
+ const prevSize = filePositions[filePath];
61
+ const newSize = stats.size;
62
+
63
+ // Only read new content
64
+ if (newSize > prevSize) {
65
+ const stream = fs.createReadStream(filePath, {
66
+ start: prevSize,
67
+ end: newSize
68
+ });
69
+
70
+ let data = "";
71
+ stream.on("data", chunk => (data += chunk));
72
+ stream.on("end", () => {
73
+ filePositions[filePath] = newSize;
74
+
75
+ const lines = data.split("\n").filter(line => line.trim() !== "");
76
+ lines.forEach(line => {
77
+ const explanation = explainError(line);
78
+ if (explanation.meaning !== "Unknown error") {
79
+ console.log("\nDetected Error:\n", explanation, "\n");
80
+ }
81
+ });
82
+ });
83
+
84
+ stream.on("error", e => console.error("Stream error:", e.message));
85
+ }
86
+ });
87
+ });
88
+ }
@@ -0,0 +1,13 @@
1
+ import { explainError } from "./engine.js";
2
+
3
+ // Express middleware to catch errors and explain them
4
+ export function errorExplainer() {
5
+ return (err, req, res, next) => {
6
+ const explanation = explainError(err.message);
7
+ res.status(500).json({
8
+ error: err.message,
9
+ meaning: explanation.meaning,
10
+ fix: explanation.fix
11
+ });
12
+ };
13
+ }
@@ -0,0 +1,287 @@
1
+ [
2
+ {
3
+ "pattern": "ECONNREFUSED",
4
+ "meaning": "Connection refused by target service",
5
+ "fix": "Start the service or check service address/port"
6
+ },
7
+ {
8
+ "pattern": "ETIMEDOUT",
9
+ "meaning": "Connection attempt timed out",
10
+ "fix": "Check network or increase timeout settings"
11
+ },
12
+ {
13
+ "pattern": "ECONNRESET",
14
+ "meaning": "Connection reset by peer",
15
+ "fix": "Retry connection or check remote service availability"
16
+ },
17
+ {
18
+ "pattern": "EADDRINUSE",
19
+ "meaning": "Address/port already in use",
20
+ "fix": "Use a different port or stop the process occupying it"
21
+ },
22
+ {
23
+ "pattern": "ENOENT",
24
+ "meaning": "No such file or directory",
25
+ "fix": "Ensure file/directory exists and path is correct"
26
+ },
27
+ {
28
+ "pattern": "EACCES",
29
+ "meaning": "Permission denied",
30
+ "fix": "Check file/directory permissions or use elevated access"
31
+ },
32
+ {
33
+ "pattern": "EPERM",
34
+ "meaning": "Operation not permitted",
35
+ "fix": "Adjust permissions or run with correct user privileges"
36
+ },
37
+ {
38
+ "pattern": "ENOTDIR",
39
+ "meaning": "Expected directory but found file",
40
+ "fix": "Use correct path or create required directory"
41
+ },
42
+ {
43
+ "pattern": "EISDIR",
44
+ "meaning": "Expected file but found directory",
45
+ "fix": "Use correct file path instead of directory"
46
+ },
47
+ {
48
+ "pattern": "ReferenceError",
49
+ "meaning": "Variable or reference not defined",
50
+ "fix": "Ensure variable is declared before use"
51
+ },
52
+ {
53
+ "pattern": "SyntaxError",
54
+ "meaning": "Code has invalid syntax",
55
+ "fix": "Fix code syntax errors before running"
56
+ },
57
+ {
58
+ "pattern": "TypeError",
59
+ "meaning": "Invalid type or undefined value used",
60
+ "fix": "Check variable types and null/undefined values"
61
+ },
62
+ {
63
+ "pattern": "RangeError",
64
+ "meaning": "Value out of allowed range",
65
+ "fix": "Check numeric values or loops for invalid limits"
66
+ },
67
+ {
68
+ "pattern": "URIError",
69
+ "meaning": "Incorrect use of encode/decode URI",
70
+ "fix": "Validate and encode URI parameters properly"
71
+ },
72
+ {
73
+ "pattern": "EvalError",
74
+ "meaning": "Issue with eval() function",
75
+ "fix": "Avoid using eval; use safer alternatives"
76
+ },
77
+ {
78
+ "pattern": "AggregateError",
79
+ "meaning": "Multiple errors aggregated",
80
+ "fix": "Inspect each error in the Aggregated error list"
81
+ },
82
+ {
83
+ "pattern": "ERR_MODULE_NOT_FOUND",
84
+ "meaning": "Module import failed",
85
+ "fix": "Check module name and installation"
86
+ },
87
+ {
88
+ "pattern": "ERR_NAPI_INVALID_DATAVIEW_ARGS",
89
+ "meaning": "Invalid DataView arguments",
90
+ "fix": "Verify DataView usage and parameters"
91
+ },
92
+ {
93
+ "pattern": "ECONNABORTED",
94
+ "meaning": "Connection aborted prematurely",
95
+ "fix": "Ensure response body is sent after write operations"
96
+ },
97
+ {
98
+ "pattern": "EHOSTUNREACH",
99
+ "meaning": "No route to host",
100
+ "fix": "Check network route and firewall settings"
101
+ },
102
+ {
103
+ "pattern": "ENOTFOUND",
104
+ "meaning": "DNS lookup failed or host not found",
105
+ "fix": "Verify hostname and network settings"
106
+ },
107
+ {
108
+ "pattern": "ERR_MULTIPLE_CALLBACK",
109
+ "meaning": "Callback called more than once",
110
+ "fix": "Ensure callback is called only once"
111
+ },
112
+ {
113
+ "pattern": "EPIPE",
114
+ "meaning": "Broken pipe or write on closed stream",
115
+ "fix": "Check stream states and request/response handling"
116
+ },
117
+ {
118
+ "pattern": "UnhandledPromiseRejection",
119
+ "meaning": "Promise rejected without a catch",
120
+ "fix": "Handle promise errors with .catch() or try/catch"
121
+ },
122
+ {
123
+ "pattern": "MemoryError",
124
+ "meaning": "Out of memory or heap exceeded",
125
+ "fix": "Optimize memory usage or increase limits"
126
+ },
127
+ {
128
+ "pattern": "ERR_ASSERTION",
129
+ "meaning": "Assertion failed",
130
+ "fix": "Check assertion conditions"
131
+ },
132
+ {
133
+ "pattern": "ValidationError",
134
+ "meaning": "Data validation failed",
135
+ "fix": "Validate inputs before processing"
136
+ },
137
+ {
138
+ "pattern": "MongoNetworkError",
139
+ "meaning": "MongoDB network connection issue",
140
+ "fix": "Check MongoDB service and network"
141
+ },
142
+ {
143
+ "pattern": "SequelizeConnectionError",
144
+ "meaning": "Database connection failed",
145
+ "fix": "Check DB credentials and server status"
146
+ },
147
+ {
148
+ "pattern": "SyntaxError: Unexpected token",
149
+ "meaning": "Invalid JSON or syntax",
150
+ "fix": "Fix JSON formatting or code syntax"
151
+ },
152
+ {
153
+ "pattern": "AxiosError",
154
+ "meaning": "HTTP request failed",
155
+ "fix": "Check URL, network, and request parameters"
156
+ },
157
+ {
158
+ "pattern": "TypeError: Cannot read property",
159
+ "meaning": "Attempted to access property of undefined",
160
+ "fix": "Check object initialization before use"
161
+ },
162
+ {
163
+ "pattern": "RangeError: Maximum call stack size exceeded",
164
+ "meaning": "Infinite recursion or deep nesting",
165
+ "fix": "Refactor recursive calls or loops"
166
+ },
167
+ {
168
+ "pattern": "EAI_AGAIN",
169
+ "meaning": "Temporary DNS failure",
170
+ "fix": "Retry DNS lookup or check network"
171
+ },
172
+ {
173
+ "pattern": "Heap out of memory",
174
+ "meaning": "Memory usage exceeded V8 heap limit",
175
+ "fix": "Increase memory limit or optimize code"
176
+ },
177
+ {
178
+ "pattern": "ERR_INVALID_ARG_TYPE",
179
+ "meaning": "Invalid argument type passed",
180
+ "fix": "Check function parameters"
181
+ },
182
+ {
183
+ "pattern": "ERR_HTTP_HEADERS_SENT",
184
+ "meaning": "Response headers already sent",
185
+ "fix": "Avoid sending multiple responses"
186
+ },
187
+ {
188
+ "pattern": "ERR_STREAM_DESTROYED",
189
+ "meaning": "Stream destroyed unexpectedly",
190
+ "fix": "Check stream lifecycle and error handling"
191
+ },
192
+ {
193
+ "pattern": "ERR_CHILD_PROCESS_STDIO_MAXBUFFER",
194
+ "meaning": "Child process output exceeded buffer limit",
195
+ "fix": "Increase maxBuffer or handle output incrementally"
196
+ },
197
+ {
198
+ "pattern": "ERR_HTTP_INVALID_HEADER_VALUE",
199
+ "meaning": "Invalid HTTP header value",
200
+ "fix": "Check header formatting and value types"
201
+ },
202
+ {
203
+ "pattern": "ERR_HTTP_INVALID_METHOD",
204
+ "meaning": "HTTP method invalid",
205
+ "fix": "Use valid HTTP methods: GET, POST, PUT, DELETE, etc."
206
+ },
207
+ {
208
+ "pattern": "ERR_HTTP_INVALID_STATUS_CODE",
209
+ "meaning": "HTTP status code is invalid",
210
+ "fix": "Use valid status codes (100–599)"
211
+ },
212
+ {
213
+ "pattern": "ERR_HTTP_INVALID_HEADER_NAME",
214
+ "meaning": "Invalid HTTP header name",
215
+ "fix": "Use valid header names"
216
+ },
217
+ {
218
+ "pattern": "ERR_HTTP2_STREAM_ERROR",
219
+ "meaning": "HTTP2 stream encountered an error",
220
+ "fix": "Check HTTP2 request/response handling"
221
+ },
222
+ {
223
+ "pattern": "ERR_HTTP2_SESSION_ERROR",
224
+ "meaning": "Error in HTTP2 session",
225
+ "fix": "Reset or recreate session"
226
+ },
227
+ {
228
+ "pattern": "ERR_TLS_CERT_ALTNAME_INVALID",
229
+ "meaning": "TLS certificate does not match hostname",
230
+ "fix": "Use correct certificate or ignore hostname check for testing"
231
+ },
232
+ {
233
+ "pattern": "ERR_TLS_HANDSHAKE",
234
+ "meaning": "TLS handshake failed",
235
+ "fix": "Check certificates and network"
236
+ },
237
+ {
238
+ "pattern": "ERR_STREAM_WRITE_AFTER_END",
239
+ "meaning": "Attempted to write to a stream after it ended",
240
+ "fix": "Ensure write happens before ending stream"
241
+ },
242
+ {
243
+ "pattern": "ERR_STREAM_ALREADY_FINISHED",
244
+ "meaning": "Stream already finished",
245
+ "fix": "Do not write or end again"
246
+ },
247
+ {
248
+ "pattern": "ERR_STREAM_CANNOT_PIPE",
249
+ "meaning": "Cannot pipe stream",
250
+ "fix": "Ensure source and destination are streams"
251
+ },
252
+ {
253
+ "pattern": "ERR_INVALID_OPT_VALUE",
254
+ "meaning": "Invalid option value provided",
255
+ "fix": "Check configuration or API option values"
256
+ },
257
+ {
258
+ "pattern": "ERR_REQUIRE_ESM",
259
+ "meaning": "Module must be imported using ESM syntax",
260
+ "fix": "Use import syntax or convert to ESM"
261
+ },
262
+ {
263
+ "pattern": "ERR_UNHANDLED_REJECTION",
264
+ "meaning": "Promise rejected without catch",
265
+ "fix": "Add catch() or try/catch around async code"
266
+ },
267
+ {
268
+ "pattern": "ERR_BUFFER_OUT_OF_BOUNDS",
269
+ "meaning": "Buffer access outside bounds",
270
+ "fix": "Validate buffer size and index"
271
+ },
272
+ {
273
+ "pattern": "ERR_INVALID_CHARACTER",
274
+ "meaning": "Unexpected character encountered",
275
+ "fix": "Check JSON, URL, or input encoding"
276
+ },
277
+ {
278
+ "pattern": "ERR_CHILD_PROCESS_KILLED",
279
+ "meaning": "Child process terminated unexpectedly",
280
+ "fix": "Check process lifecycle and signals"
281
+ },
282
+ {
283
+ "pattern": "UnhandledPromiseRejectionWarning",
284
+ "meaning": "Promise rejection not handled",
285
+ "fix": "Add catch handlers for promises"
286
+ }
287
+ ]
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "errorxplain",
3
+ "version": "1.0.0",
4
+ "description": "Intelligent Error Explainer CLI & Middleware for backend developers",
5
+ "main": "lib/engine.js",
6
+ "bin": {
7
+ "errorxplain": "./bin/errx.js"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "start": "node bin/errx.js"
12
+ },
13
+ "keywords": [
14
+ "error",
15
+ "debug",
16
+ "cli",
17
+ "middleware",
18
+ "backend",
19
+ "developer-tools",
20
+ "error-explainer",
21
+ "error-debugger",
22
+ "errorxplain"
23
+ ],
24
+ "author": "Shashank Neupane",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "read-last-lines": "^1.8.0"
28
+ }
29
+ }