start working on handling the validation errors

This commit is contained in:
Sina Atalay 2024-02-07 20:24:05 +01:00
parent 48d48f4bf2
commit 303da319ec
1 changed files with 66 additions and 10 deletions

View File

@ -1,5 +1,5 @@
import time
from typing import Callable
import re
import rich
import rich.console
@ -8,7 +8,10 @@ import rich.live
import rich.table
import rich.text
import rich.progress
import pydantic_core
import pydantic
import ruamel.yaml
import ruamel.yaml.parser
console = rich.console.Console()
@ -17,7 +20,7 @@ def welcome():
"""Print a welcome message to the terminal."""
table = rich.table.Table(
title="\nWelcome to [bold]Render[dodger_blue3]CV[/dodger_blue3][/bold]!",
title_justify="center",
title_justify="left",
)
table.add_column("Title", style="magenta")
@ -28,17 +31,17 @@ def welcome():
table.add_row("Bug reports", "https://github.com/sinaatalay/rendercv/issues/")
table.add_row("Feature requests", "https://github.com/sinaatalay/rendercv/issues/")
console.print(table, justify="center")
console.print(table)
def warning(text):
"""Print a warning message to the terminal."""
console.print(f"[bold yellow]{text}[/bold yellow]")
console.print(f"[bold yellow]{text}")
def error(text):
def error(text, exception=None):
"""Print an error message to the terminal."""
console.print(f"[bold red]{text}[/bold red]")
console.print(f"\n[bold red]{text}[/bold red]\n\n[orange4]{exception}")
def information(text):
@ -46,11 +49,63 @@ def information(text):
console.print(f"[bold green]{text}")
def handle_validation_error(exception: pydantic.ValidationError):
error_dictionary: dict[str, str] = {
r"Value error, Invalid isoformat string: '(.*)'": (
"This is not a valid date! Please use either YYYY-MM-DD, YYYY-MM, or"
" YYYY format."
),
r"URL scheme should be 'http' or 'https'": "This is not a valid URL!",
r"Field( )required": "This field is required!",
r"value is not a valid phone number": "This is not a valid phone number!",
r"String should match pattern '\\d\+\\\.\?\\d\* \*\(cm\|in\|pt\|mm\|ex\|em\)'": (
'This is not a valid dimension! For example, use "2 cm" or "3.5 in"'
),
}
new_errors: list[pydantic_core.ErrorDetails] = []
for error_object in exception.errors():
for key, value in error_dictionary.items():
match = re.match(key, error_object["msg"])
if match:
error_object["msg"] = value
try:
error_object["input"] = match.group(1)
except IndexError:
pass
new_errors.append(error_object)
table = rich.table.Table(
title="[bold red]\nThere are some errors in the input file!\n",
title_justify="left",
show_lines=True,
)
table.add_column("Location", style="cyan", no_wrap=True)
table.add_column("Input Value", style="magenta")
table.add_column("Error Message", style="orange4")
for error_object in new_errors:
table.add_row(
".".join([str(i) for i in error_object["loc"]]),
error_object["input"],
error_object["msg"],
)
console.print(table)
def handle_exceptions(function: Callable) -> Callable:
""" """
def wrapper(*args, **kwargs):
return function(*args, **kwargs)
try:
function(*args, **kwargs)
except pydantic.ValidationError as e:
handle_validation_error(e)
except ruamel.yaml.YAMLError as e:
error("There is a YAML error in the input file!", e)
except RuntimeError as e:
error("An error occurred:", e)
return wrapper
@ -63,7 +118,7 @@ class LiveProgressReporter(rich.live.Live):
number_of_steps (int): The number of steps to be finished.
"""
def __init__(self, number_of_steps: int):
def __init__(self, number_of_steps: int, end_message: str = "Your CV is rendered!"):
class TimeElapsedColumn(rich.progress.ProgressColumn):
def render(self, task: "rich.progress.Task") -> rich.text.Text:
elapsed = task.finished_time if task.finished else task.elapsed
@ -89,6 +144,7 @@ class LiveProgressReporter(rich.live.Live):
self.overall_task_id = self.overall_progress.add_task("", total=number_of_steps)
self.number_of_steps = number_of_steps
self.end_message = end_message
self.current_step = 0
self.overall_progress.update(
self.overall_task_id,
@ -133,5 +189,5 @@ class LiveProgressReporter(rich.live.Live):
"""End the live progress reporting."""
self.overall_progress.update(
self.overall_task_id,
description="[bold green]Your CV is rendered!",
description=f"[bold green]{self.end_message}",
)