Skip to content

Commit 94945d3

Browse files
committed
Colored error messages for common errors
1 parent f341425 commit 94945d3

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

src/dotcat/dotcat.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ def bold(text: str) -> str:
6060
return f"\033[1m{text}\033[0m"
6161

6262

63+
def red(text: str) -> str:
64+
"""
65+
Returns the given text formatted in red.
66+
67+
Args:
68+
text: The text to format.
69+
70+
Returns:
71+
The formatted text.
72+
"""
73+
return f"\033[31m{text}\033[0m"
74+
75+
6376
USAGE = f"""
6477
{bold('dotcat')}
6578
Read values, including nested values, from structured data files (JSON, YAML, TOML, INI)
@@ -115,7 +128,9 @@ def parse_yaml(file: StringIO) -> ParsedData:
115128
try:
116129
return yaml.safe_load(file)
117130
except yaml.YAMLError as e:
118-
raise ParseError(f"[ERROR] {file.name}: Unable to parse YAML file: {str(e)}")
131+
raise ParseError(
132+
f"{red('[ERROR]')} {file.name}: Unable to parse YAML file: {str(e)}"
133+
)
119134

120135

121136
def parse_json(file: StringIO) -> ParsedData:
@@ -133,7 +148,9 @@ def parse_json(file: StringIO) -> ParsedData:
133148
try:
134149
return json.load(file)
135150
except json.JSONDecodeError as e:
136-
raise ParseError(f"[ERROR] {file.name}: Unable to parse JSON file: {str(e)}")
151+
raise ParseError(
152+
f"{red('[ERROR]')} {file.name}: Unable to parse JSON file: {str(e)}"
153+
)
137154

138155

139156
def parse_toml(file: StringIO) -> ParsedData:
@@ -151,7 +168,9 @@ def parse_toml(file: StringIO) -> ParsedData:
151168
try:
152169
return toml.load(file)
153170
except toml.TomlDecodeError as e:
154-
raise ParseError(f"[ERROR] {file.name}: Unable to parse TOML file: {str(e)}")
171+
raise ParseError(
172+
f"{red('[ERROR]')} {file.name}: Unable to parse TOML file: {str(e)}"
173+
)
155174

156175

157176
FORMATS = [
@@ -179,18 +198,18 @@ def parse_file(filename: str) -> ParsedData:
179198
with open(filename, "r") as file:
180199
content = file.read().strip()
181200
if not content:
182-
raise ValueError(f"[ERROR] {filename}: File is empty")
201+
raise ValueError(f"{red('[ERROR]')} {filename}: File is empty")
183202
for parser in parsers:
184203
try:
185204
return parser(StringIO(content))
186205
except ParseError:
187206
continue
188207
msg = "Unsupported file format. Supported formats: JSON, YAML, TOML, INI"
189-
raise ValueError(f"[ERROR] { filename}:{msg} ")
208+
raise ValueError(f"{red('[ERROR]')} {filename}: {msg}")
190209
except FileNotFoundError:
191-
raise FileNotFoundError(f"[ERROR] {filename}: File not found")
210+
raise FileNotFoundError(f"{red('[ERROR]')} {filename}: File not found")
192211
except Exception as e:
193-
raise ValueError(f"[ERROR] {filename}: Unable to parse file: {str(e)}")
212+
raise ValueError(f"{red('[ERROR]')} {filename}: Unable to parse file: {str(e)}")
194213

195214

196215
######################################################################
@@ -288,7 +307,7 @@ def from_attr_chain(data: Dict[str, Any], lookup_chain: str) -> Any:
288307
"""
289308
if data is None:
290309
chain = lookup_chain.split(".")[0]
291-
raise KeyError(f"[ERROR] key '{bold({chain})}' not found in {italics('')}")
310+
raise KeyError(f"{red('[ERROR] k')}ey '{chain}' not found in {italics('')}")
292311
found_keys = []
293312
for key in lookup_chain.split("."):
294313
if LIST_ACCESS_SYMBOL in key:
@@ -298,7 +317,7 @@ def from_attr_chain(data: Dict[str, Any], lookup_chain: str) -> Any:
298317
data = data.get(key)
299318
if data is None:
300319
keys = ".".join(found_keys)
301-
raise KeyError(f"[ERROR] key '{key}' not found in { keys}")
320+
raise KeyError(f"{red('[ERROR]')} key '{red(key)}' not found in {keys}")
302321
found_keys.append(key)
303322
return data
304323

@@ -399,9 +418,9 @@ def run(args: List[str] = None) -> None:
399418
if os.path.exists(filename):
400419
# File exists, but dot pattern is missing
401420
print(
402-
f"Dot path required. Which value do you want me to look up in {filename}?"
421+
f"{red('Dot')} path required. {red('Which')} value do you want me to look up in {filename}?"
403422
)
404-
print(f"\n$dotcat {filename} <pattern>")
423+
print(f"\n$dotcat {filename} {red('<pattern>')}")
405424
sys.exit(2) # Invalid usage
406425
except Exception:
407426
# If there's any error checking the file, fall back to general usage message
@@ -412,9 +431,9 @@ def run(args: List[str] = None) -> None:
412431
if "." in lookup_chain:
413432
# It looks like a dot path, so assume the file is missing
414433
print(
415-
f"File path required. Which file contains the value at {lookup_chain}?"
434+
f"{red('File')} path required. {red('Which')} file contains the value at {lookup_chain}?"
416435
)
417-
print(f"\n$dotcat <file> {lookup_chain}")
436+
print(f"\n$dotcat {red('<file>')} {lookup_chain}")
418437
sys.exit(2) # Invalid usage
419438
# Otherwise, it might be a file without an extension or something else,
420439
# so fall back to the general usage message
@@ -427,18 +446,18 @@ def run(args: List[str] = None) -> None:
427446
try:
428447
data = parse_file(filename)
429448
except FileNotFoundError as e:
430-
print(e)
449+
print(red(str(e)))
431450
sys.exit(3) # File not found
432451
except ValueError as e:
433-
print(e)
452+
print(red(str(e)))
434453
sys.exit(4) # Parsing error
435454

436455
# get the value at the specified key
437456
try:
438457
value = from_attr_chain(data, lookup_chain)
439458
print(format_output(value, output_format))
440459
except KeyError as e:
441-
print(f"[ERROR] {filename}: " + e.args[0].strip('"'))
460+
print(f"{red('[ERROR]')} {filename}: " + e.args[0].strip('"'))
442461
sys.exit(5) # Key not found
443462

444463

0 commit comments

Comments
 (0)