error-translator-cli-v2 1.1.5__tar.gz → 2.0.0__tar.gz
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.
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/PKG-INFO +7 -1
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/README.md +6 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/pyproject.toml +1 -1
- error_translator_cli_v2-2.0.0/src/error_translator/cli.py +265 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/core.py +1 -1
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/PKG-INFO +7 -1
- error_translator_cli_v2-1.1.5/src/error_translator/cli.py +0 -207
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/LICENSE +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/setup.cfg +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/__init__.py +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/auto.py +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/rules.json +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/SOURCES.txt +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/dependency_links.txt +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/entry_points.txt +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/requires.txt +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/top_level.txt +0 -0
- {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/tests/test_core.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: error-translator-cli-v2
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
|
|
5
5
|
Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
|
|
6
6
|
License: MIT License
|
|
@@ -90,6 +90,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
|
|
|
90
90
|
## Key Features
|
|
91
91
|
|
|
92
92
|
* **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
|
|
93
|
+
* **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
|
|
93
94
|
* **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
|
|
94
95
|
* **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
|
|
95
96
|
* **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
|
|
@@ -137,6 +138,11 @@ explain-error --json "NameError: name 'x' is not defined"
|
|
|
137
138
|
# {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
|
|
138
139
|
```
|
|
139
140
|
|
|
141
|
+
Show an about screen with project metadata and quick usage examples:
|
|
142
|
+
```bash
|
|
143
|
+
explain-error --about
|
|
144
|
+
```
|
|
145
|
+
|
|
140
146
|
The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
|
|
141
147
|
|
|
142
148
|
### 2. Automatic Import Hook
|
|
@@ -25,6 +25,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
|
|
|
25
25
|
## Key Features
|
|
26
26
|
|
|
27
27
|
* **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
|
|
28
|
+
* **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
|
|
28
29
|
* **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
|
|
29
30
|
* **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
|
|
30
31
|
* **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
|
|
@@ -72,6 +73,11 @@ explain-error --json "NameError: name 'x' is not defined"
|
|
|
72
73
|
# {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
|
|
73
74
|
```
|
|
74
75
|
|
|
76
|
+
Show an about screen with project metadata and quick usage examples:
|
|
77
|
+
```bash
|
|
78
|
+
explain-error --about
|
|
79
|
+
```
|
|
80
|
+
|
|
75
81
|
The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
|
|
76
82
|
|
|
77
83
|
### 2. Automatic Import Hook
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "error-translator-cli-v2"
|
|
7
|
-
version = "
|
|
7
|
+
version = "2.0.0"
|
|
8
8
|
description = "Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
import argparse
|
|
4
|
+
from .core import translate_error
|
|
5
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
6
|
+
|
|
7
|
+
# Import Rich UI Components
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.panel import Panel
|
|
10
|
+
from rich.syntax import Syntax
|
|
11
|
+
from rich.text import Text
|
|
12
|
+
from rich.table import Table
|
|
13
|
+
from rich import box
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
VERSION = version("error-translator-cli-v2")
|
|
17
|
+
except PackageNotFoundError:
|
|
18
|
+
VERSION = "unknown (not installed via pip)"
|
|
19
|
+
|
|
20
|
+
# Initialize the global rich console
|
|
21
|
+
console = Console()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _print_title_banner():
|
|
25
|
+
banner = Text()
|
|
26
|
+
banner.append("Error Translator CLI\n", style="bold bright_magenta")
|
|
27
|
+
banner.append("Translate Python tracebacks into clear, actionable guidance.", style="cyan")
|
|
28
|
+
console.print(
|
|
29
|
+
Panel(
|
|
30
|
+
banner,
|
|
31
|
+
border_style="magenta",
|
|
32
|
+
padding=(1, 2),
|
|
33
|
+
expand=False,
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def print_about():
|
|
38
|
+
"""Prints a polished about view using rich components."""
|
|
39
|
+
_print_title_banner()
|
|
40
|
+
|
|
41
|
+
meta = Table.grid(padding=(0, 1))
|
|
42
|
+
meta.add_column(style="bold white", justify="right")
|
|
43
|
+
meta.add_column(style="green")
|
|
44
|
+
meta.add_row("Version", VERSION)
|
|
45
|
+
meta.add_row("Author", "Gourabananda Datta")
|
|
46
|
+
meta.add_row("Repository", "https://github.com/gourabanandad/error-translator-cli-v2")
|
|
47
|
+
console.print(Panel(meta, title="[bold cyan]Project[/]", border_style="cyan", expand=False))
|
|
48
|
+
|
|
49
|
+
features = Text()
|
|
50
|
+
features.append("• Offline and fast translation\n", style="white")
|
|
51
|
+
features.append("• Human-readable explanations\n", style="white")
|
|
52
|
+
features.append("• Actionable fix suggestions\n", style="white")
|
|
53
|
+
features.append("• Optional AST-level insight", style="white")
|
|
54
|
+
console.print(Panel(features, title="[bold green]Features[/]", border_style="green", expand=False))
|
|
55
|
+
|
|
56
|
+
examples = Text()
|
|
57
|
+
examples.append("explain-error run your_script.py\n", style="bold cyan")
|
|
58
|
+
examples.append("explain-error \"TypeError: ...\"\n", style="bold cyan")
|
|
59
|
+
examples.append("cat error.log | explain-error", style="bold cyan")
|
|
60
|
+
console.print(Panel(examples, title="[bold yellow]Quick Start[/]", border_style="yellow", expand=False))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def print_result(result: dict):
|
|
64
|
+
"""Print translated output in a polished, professional layout."""
|
|
65
|
+
console.print()
|
|
66
|
+
|
|
67
|
+
if result.get("error") and not result.get("matched_error"):
|
|
68
|
+
message = result.get("message", "An unexpected error occurred.")
|
|
69
|
+
console.print(
|
|
70
|
+
Panel(
|
|
71
|
+
f"[bold red]{message}[/]",
|
|
72
|
+
title="[bold red]Error[/]",
|
|
73
|
+
border_style="red",
|
|
74
|
+
box=box.ROUNDED,
|
|
75
|
+
expand=False,
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
error_title = result.get("matched_error", "Unknown Error")
|
|
81
|
+
console.print(
|
|
82
|
+
Panel(
|
|
83
|
+
f"[bold white]{error_title}[/]",
|
|
84
|
+
title="[bold red]Detected Error[/]",
|
|
85
|
+
border_style="red",
|
|
86
|
+
box=box.ROUNDED,
|
|
87
|
+
expand=False,
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
file_name = result.get("file")
|
|
92
|
+
line_no = result.get("line", "?")
|
|
93
|
+
if file_name and file_name != "Unknown File":
|
|
94
|
+
console.print(
|
|
95
|
+
Panel(
|
|
96
|
+
f"[yellow]File:[/] {file_name}\n[yellow]Line:[/] {line_no}",
|
|
97
|
+
title="[bold yellow]Location[/]",
|
|
98
|
+
border_style="yellow",
|
|
99
|
+
box=box.ROUNDED,
|
|
100
|
+
expand=False,
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if result.get("code"):
|
|
105
|
+
try:
|
|
106
|
+
start_line = int(line_no)
|
|
107
|
+
except (TypeError, ValueError):
|
|
108
|
+
start_line = 1
|
|
109
|
+
|
|
110
|
+
syntax = Syntax(
|
|
111
|
+
result["code"],
|
|
112
|
+
"python",
|
|
113
|
+
theme="monokai",
|
|
114
|
+
line_numbers=True,
|
|
115
|
+
start_line=start_line,
|
|
116
|
+
word_wrap=True,
|
|
117
|
+
)
|
|
118
|
+
console.print(Panel(syntax, title="[bold blue]Code Context[/]", border_style="blue", box=box.ROUNDED))
|
|
119
|
+
|
|
120
|
+
explanation = result.get("explanation", "No explanation available.")
|
|
121
|
+
console.print(
|
|
122
|
+
Panel(
|
|
123
|
+
f"[white]{explanation}[/]",
|
|
124
|
+
title="[bold cyan]Explanation[/]",
|
|
125
|
+
title_align="left",
|
|
126
|
+
border_style="cyan",
|
|
127
|
+
box=box.ROUNDED,
|
|
128
|
+
expand=False,
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
fix = result.get("fix", "No suggested fix available.")
|
|
133
|
+
console.print(
|
|
134
|
+
Panel(
|
|
135
|
+
f"[bold green]{fix}[/]",
|
|
136
|
+
title="[bold green]Suggested Fix[/]",
|
|
137
|
+
title_align="left",
|
|
138
|
+
border_style="green",
|
|
139
|
+
box=box.ROUNDED,
|
|
140
|
+
expand=False,
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if result.get("ast_insight"):
|
|
145
|
+
console.print(
|
|
146
|
+
Panel(
|
|
147
|
+
f"[white]{result['ast_insight']}[/]",
|
|
148
|
+
title="[bold magenta]AST Insight[/]",
|
|
149
|
+
title_align="left",
|
|
150
|
+
border_style="magenta",
|
|
151
|
+
box=box.ROUNDED,
|
|
152
|
+
expand=False,
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def print_result_json(result: dict):
|
|
158
|
+
"""Prints the translated error as a single-line JSON object on stdout."""
|
|
159
|
+
print(json.dumps(result, ensure_ascii=False))
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def run_script(script_name: str, *, as_json: bool = False):
|
|
163
|
+
"""Run a Python script and translate traceback output if it fails."""
|
|
164
|
+
import subprocess
|
|
165
|
+
try:
|
|
166
|
+
result = subprocess.run(
|
|
167
|
+
[sys.executable, script_name],
|
|
168
|
+
capture_output=True,
|
|
169
|
+
text=True
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if result.returncode == 0:
|
|
173
|
+
print(result.stdout, end="")
|
|
174
|
+
else:
|
|
175
|
+
if result.stdout:
|
|
176
|
+
print(result.stdout, end="")
|
|
177
|
+
|
|
178
|
+
translation = translate_error(result.stderr)
|
|
179
|
+
if as_json:
|
|
180
|
+
print_result_json(translation)
|
|
181
|
+
else:
|
|
182
|
+
print_result(translation)
|
|
183
|
+
|
|
184
|
+
except FileNotFoundError:
|
|
185
|
+
if as_json:
|
|
186
|
+
print(json.dumps({
|
|
187
|
+
"error": "script_not_found",
|
|
188
|
+
"message": f"Could not find script '{script_name}'",
|
|
189
|
+
}))
|
|
190
|
+
else:
|
|
191
|
+
console.print(
|
|
192
|
+
Panel(
|
|
193
|
+
f"[bold red]Could not find script '{script_name}'[/]",
|
|
194
|
+
title="[bold red]Execution Error[/]",
|
|
195
|
+
border_style="red",
|
|
196
|
+
box=box.ROUNDED,
|
|
197
|
+
expand=False,
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
except Exception as exc:
|
|
201
|
+
if as_json:
|
|
202
|
+
print(json.dumps({
|
|
203
|
+
"error": "runtime_failure",
|
|
204
|
+
"message": str(exc),
|
|
205
|
+
}))
|
|
206
|
+
else:
|
|
207
|
+
console.print(
|
|
208
|
+
Panel(
|
|
209
|
+
f"[bold red]{exc}[/]",
|
|
210
|
+
title="[bold red]Runtime Error[/]",
|
|
211
|
+
border_style="red",
|
|
212
|
+
box=box.ROUNDED,
|
|
213
|
+
expand=False,
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
def main():
|
|
218
|
+
parser = argparse.ArgumentParser(
|
|
219
|
+
prog="explain-error",
|
|
220
|
+
description="Error Translator — Turn cryptic Python tracebacks into clear, actionable advice.",
|
|
221
|
+
epilog="""
|
|
222
|
+
Examples:
|
|
223
|
+
explain-error run my_script.py
|
|
224
|
+
explain-error "NameError: name 'usr_count' is not defined"
|
|
225
|
+
cat error.log | explain-error
|
|
226
|
+
""",
|
|
227
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
parser.add_argument("-a", "--about", action="store_true", help="Display information about the tool.")
|
|
231
|
+
parser.add_argument("-v", "--version", action="store_true", help="Show the current version of the tool.")
|
|
232
|
+
parser.add_argument("--json", action="store_true", dest="as_json", help="Output the translated error as a JSON object.")
|
|
233
|
+
parser.add_argument("args", nargs="*", help="Positional arguments.")
|
|
234
|
+
|
|
235
|
+
parsed_args = parser.parse_args()
|
|
236
|
+
|
|
237
|
+
if parsed_args.about:
|
|
238
|
+
print_about()
|
|
239
|
+
sys.exit(0)
|
|
240
|
+
|
|
241
|
+
if parsed_args.version:
|
|
242
|
+
console.print(f"Error Translator CLI Version: [bold green]{VERSION}[/]")
|
|
243
|
+
sys.exit(0)
|
|
244
|
+
|
|
245
|
+
emit = print_result_json if parsed_args.as_json else print_result
|
|
246
|
+
|
|
247
|
+
if not sys.stdin.isatty():
|
|
248
|
+
error_input = sys.stdin.read()
|
|
249
|
+
if error_input.strip():
|
|
250
|
+
emit(translate_error(error_input))
|
|
251
|
+
return
|
|
252
|
+
|
|
253
|
+
if not parsed_args.args:
|
|
254
|
+
parser.print_help()
|
|
255
|
+
sys.exit(1)
|
|
256
|
+
|
|
257
|
+
if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
|
|
258
|
+
script_name = parsed_args.args[1]
|
|
259
|
+
run_script(script_name, as_json=parsed_args.as_json)
|
|
260
|
+
else:
|
|
261
|
+
error_input = " ".join(parsed_args.args)
|
|
262
|
+
emit(translate_error(error_input))
|
|
263
|
+
|
|
264
|
+
if __name__ == "__main__":
|
|
265
|
+
main()
|
{error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/core.py
RENAMED
|
@@ -90,7 +90,7 @@ def translate_error(traceback_text: str) -> dict:
|
|
|
90
90
|
insight = None
|
|
91
91
|
|
|
92
92
|
if handler_function and file_name != "Unknown File":
|
|
93
|
-
insight = handler_function(file_name, extracted_values)
|
|
93
|
+
insight = handler_function(file_name, line_number, extracted_values)
|
|
94
94
|
|
|
95
95
|
return {
|
|
96
96
|
"explanation": rule["explanation"].format(*extracted_values),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: error-translator-cli-v2
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
|
|
5
5
|
Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
|
|
6
6
|
License: MIT License
|
|
@@ -90,6 +90,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
|
|
|
90
90
|
## Key Features
|
|
91
91
|
|
|
92
92
|
* **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
|
|
93
|
+
* **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
|
|
93
94
|
* **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
|
|
94
95
|
* **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
|
|
95
96
|
* **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
|
|
@@ -137,6 +138,11 @@ explain-error --json "NameError: name 'x' is not defined"
|
|
|
137
138
|
# {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
|
|
138
139
|
```
|
|
139
140
|
|
|
141
|
+
Show an about screen with project metadata and quick usage examples:
|
|
142
|
+
```bash
|
|
143
|
+
explain-error --about
|
|
144
|
+
```
|
|
145
|
+
|
|
140
146
|
The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
|
|
141
147
|
|
|
142
148
|
### 2. Automatic Import Hook
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import sys
|
|
3
|
-
import argparse
|
|
4
|
-
from .core import translate_error
|
|
5
|
-
from importlib.metadata import version, PackageNotFoundError
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
VERSION = version("error-translator-cli-v2")
|
|
9
|
-
except PackageNotFoundError:
|
|
10
|
-
VERSION = "unknown (not installed via pip)" # Fallback version if package metadata is not found
|
|
11
|
-
|
|
12
|
-
# ANSI Color Codes
|
|
13
|
-
class Colors:
|
|
14
|
-
RED = '\033[91m'
|
|
15
|
-
GREEN = '\033[92m'
|
|
16
|
-
YELLOW = '\033[93m'
|
|
17
|
-
CYAN = '\033[96m'
|
|
18
|
-
BOLD = '\033[1m'
|
|
19
|
-
RESET = '\033[0m'
|
|
20
|
-
MAGENTA = '\033[95m'
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def print_about():
|
|
24
|
-
"""Prints the about message for the tool."""
|
|
25
|
-
about_text = f"""
|
|
26
|
-
ERROR TRANSLATOR CLI
|
|
27
|
-
=====================
|
|
28
|
-
A lightning-fast, offline tool that translates raw Python tracebacks
|
|
29
|
-
into human-readable explanations with actionable fixes.
|
|
30
|
-
|
|
31
|
-
Authors: Gourabananda Datta
|
|
32
|
-
Repository: https://github.com/gourabanandad/error-translator-cli-v2
|
|
33
|
-
Usage:
|
|
34
|
-
1. Run a script and translate its errors:
|
|
35
|
-
explain-error run your_script.py
|
|
36
|
-
2. Translate an error message directly:
|
|
37
|
-
explain-error "TypeError: unsupported operand type(s) for +: 'int' and 'str'"
|
|
38
|
-
3. Pipe an error log:
|
|
39
|
-
cat error.log | explain-error
|
|
40
|
-
4. Get help:
|
|
41
|
-
explain-error --help
|
|
42
|
-
5. About:
|
|
43
|
-
explain-error --about
|
|
44
|
-
"""
|
|
45
|
-
print(f"\033[96m{about_text}\033[0m")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def print_result(result: dict):
|
|
49
|
-
"""Prints the translated error to the terminal with colors."""
|
|
50
|
-
print(f"\n{Colors.RED}{Colors.BOLD} Error Detected:{Colors.RESET}")
|
|
51
|
-
print(f"{result.get('matched_error', 'N/A')}")
|
|
52
|
-
|
|
53
|
-
if "file" in result:
|
|
54
|
-
print(f"{Colors.YELLOW} Location: {result['file']} (Line {result['line']}){Colors.RESET}\n")
|
|
55
|
-
if result.get("code"):
|
|
56
|
-
print(f"{Colors.RESET} |")
|
|
57
|
-
print(f"{Colors.RESET} | {Colors.RED}{result['code']}{Colors.RESET}")
|
|
58
|
-
print(f"{Colors.RESET} |\n")
|
|
59
|
-
else:
|
|
60
|
-
print("\n")
|
|
61
|
-
|
|
62
|
-
else:
|
|
63
|
-
print()
|
|
64
|
-
|
|
65
|
-
print(f"{Colors.CYAN}{Colors.BOLD} Explanation:{Colors.RESET}")
|
|
66
|
-
print(f"{result['explanation']}\n")
|
|
67
|
-
|
|
68
|
-
print(f"{Colors.GREEN}{Colors.BOLD} Suggested Fix:{Colors.RESET}")
|
|
69
|
-
print(f"{result['fix']}\n")
|
|
70
|
-
|
|
71
|
-
if result.get("ast_insight"):
|
|
72
|
-
print(f"{Colors.MAGENTA}{Colors.BOLD} AST Insight:{Colors.RESET}")
|
|
73
|
-
print(f"{result['ast_insight']}\n")
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def print_result_json(result: dict):
|
|
77
|
-
"""Prints the translated error as a single-line JSON object on stdout.
|
|
78
|
-
|
|
79
|
-
Useful for scripting and automation: pipe the output to `jq`, parse it
|
|
80
|
-
in another language, or store it as structured logs.
|
|
81
|
-
"""
|
|
82
|
-
print(json.dumps(result, ensure_ascii=False))
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def run_script(script_name: str, *, as_json: bool = False):
|
|
86
|
-
"""Runs a python script in the background and catches its errors."""
|
|
87
|
-
import subprocess
|
|
88
|
-
try:
|
|
89
|
-
# Run the script using the current Python environment
|
|
90
|
-
result = subprocess.run(
|
|
91
|
-
[sys.executable, script_name],
|
|
92
|
-
capture_output=True,
|
|
93
|
-
text=True
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
# If the script ran perfectly (Return Code 0), print standard output
|
|
97
|
-
if result.returncode == 0:
|
|
98
|
-
print(result.stdout, end="")
|
|
99
|
-
|
|
100
|
-
# If the script crashed, print whatever succeeded, THEN translate the error
|
|
101
|
-
else:
|
|
102
|
-
if result.stdout:
|
|
103
|
-
print(result.stdout, end="")
|
|
104
|
-
|
|
105
|
-
translation = translate_error(result.stderr)
|
|
106
|
-
if as_json:
|
|
107
|
-
print_result_json(translation)
|
|
108
|
-
else:
|
|
109
|
-
print_result(translation)
|
|
110
|
-
|
|
111
|
-
except FileNotFoundError:
|
|
112
|
-
if as_json:
|
|
113
|
-
print(json.dumps({
|
|
114
|
-
"error": "script_not_found",
|
|
115
|
-
"message": f"Could not find script '{script_name}'",
|
|
116
|
-
}))
|
|
117
|
-
else:
|
|
118
|
-
print(f"{Colors.RED}Error: Could not find script '{script_name}'{Colors.RESET}")
|
|
119
|
-
|
|
120
|
-
# Entry point of the program
|
|
121
|
-
def main():
|
|
122
|
-
parser = argparse.ArgumentParser(
|
|
123
|
-
prog="explain-error",
|
|
124
|
-
description="Error Translator — Turn cryptic Python tracebacks into clear, actionable advice.",
|
|
125
|
-
epilog="""
|
|
126
|
-
Examples:
|
|
127
|
-
# Run a Python script and translate any unhandled errors
|
|
128
|
-
explain-error run my_script.py
|
|
129
|
-
|
|
130
|
-
# Translate a raw error string directly
|
|
131
|
-
explain-error "NameError: name 'usr_count' is not defined"
|
|
132
|
-
|
|
133
|
-
# Pipe a traceback from a log file or another command
|
|
134
|
-
cat error.log | explain-error
|
|
135
|
-
|
|
136
|
-
For more information, visit: https://github.com/gourabanandad/error-translator
|
|
137
|
-
""",
|
|
138
|
-
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
parser.add_argument(
|
|
142
|
-
"-a",
|
|
143
|
-
"--about",
|
|
144
|
-
action="store_true",
|
|
145
|
-
help="Display information about the tool."
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
parser.add_argument(
|
|
149
|
-
"-v",
|
|
150
|
-
"--version",
|
|
151
|
-
action="store_true",
|
|
152
|
-
help="Show the current version of the tool."
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
parser.add_argument(
|
|
156
|
-
"--json",
|
|
157
|
-
action="store_true",
|
|
158
|
-
dest="as_json",
|
|
159
|
-
help="Output the translated error as a single JSON object on stdout (useful for scripting)."
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
parser.add_argument(
|
|
163
|
-
"args",
|
|
164
|
-
nargs="*",
|
|
165
|
-
help=(
|
|
166
|
-
"Positional arguments. Use 'run <script.py>' to execute a Python file, "
|
|
167
|
-
"or provide an error string to translate. If no arguments are given and "
|
|
168
|
-
"stdin is not piped, this help message is displayed."
|
|
169
|
-
)
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
parsed_args = parser.parse_args()
|
|
173
|
-
|
|
174
|
-
if parsed_args.about:
|
|
175
|
-
print_about()
|
|
176
|
-
sys.exit(0)
|
|
177
|
-
|
|
178
|
-
if parsed_args.version:
|
|
179
|
-
print(f"Error Translator CLI Version: {Colors.GREEN}{VERSION}{Colors.RESET}")
|
|
180
|
-
sys.exit(0)
|
|
181
|
-
|
|
182
|
-
emit = print_result_json if parsed_args.as_json else print_result
|
|
183
|
-
|
|
184
|
-
# 1. Handle Piped Input (e.g., cat error.log | explain-error)
|
|
185
|
-
if not sys.stdin.isatty():
|
|
186
|
-
error_input = sys.stdin.read()
|
|
187
|
-
if error_input.strip():
|
|
188
|
-
emit(translate_error(error_input))
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
# 2. Print help if no arguments and no piped input
|
|
192
|
-
if not parsed_args.args:
|
|
193
|
-
parser.print_help()
|
|
194
|
-
sys.exit(1)
|
|
195
|
-
|
|
196
|
-
# 3. Check if the user used the "run" command
|
|
197
|
-
if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
|
|
198
|
-
script_name = parsed_args.args[1]
|
|
199
|
-
run_script(script_name, as_json=parsed_args.as_json)
|
|
200
|
-
|
|
201
|
-
# 4. Fallback: Treat the input as a raw error string
|
|
202
|
-
else:
|
|
203
|
-
error_input = " ".join(parsed_args.args)
|
|
204
|
-
emit(translate_error(error_input))
|
|
205
|
-
|
|
206
|
-
if __name__ == "__main__":
|
|
207
|
-
main()
|
|
File without changes
|
|
File without changes
|
{error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/__init__.py
RENAMED
|
File without changes
|
{error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/auto.py
RENAMED
|
File without changes
|
{error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/rules.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|