mirror of https://github.com/eyhc1/rendercv.git
improve logger
This commit is contained in:
parent
36db448628
commit
73a10bb124
|
@ -38,16 +38,23 @@ def user_friendly_errors(func: Callable) -> Callable:
|
|||
except ValidationError as e:
|
||||
# It is a Pydantic error
|
||||
error_messages = []
|
||||
error_messages.append("There are validation errors!")
|
||||
error_messages.append("There are some problems with your input 🧐")
|
||||
|
||||
# Translate Pydantic's error messages to make them more user-friendly
|
||||
custom_error_messages_by_type = {
|
||||
"url_scheme": "This is not a valid URL 😿",
|
||||
"string_type": "This is not a valid string 🤭",
|
||||
"missing": "This field is required, but it is missing 😆",
|
||||
"literal_error": "Only the following values are allowed: {expected} 😒",
|
||||
}
|
||||
custom_error_messages_by_msg = {
|
||||
"value is not a valid phone number": (
|
||||
"This is not a valid phone number 👺"
|
||||
)
|
||||
),
|
||||
"String should match pattern '\\d+\\.?\\d* *(cm|in|pt|mm|ex|em)'": (
|
||||
"This is not a valid length! Use a number followed by a unit "
|
||||
"of length (cm, in, pt, mm, ex, em) 👺"
|
||||
),
|
||||
}
|
||||
new_errors: list[ErrorDetails] = []
|
||||
for error in e.errors():
|
||||
|
@ -68,21 +75,34 @@ def user_friendly_errors(func: Callable) -> Callable:
|
|||
|
||||
if custom_message:
|
||||
ctx = error.get("ctx")
|
||||
error["msg"] = (
|
||||
custom_message.format(**ctx) if ctx else custom_message
|
||||
)
|
||||
if ctx:
|
||||
if ctx.get("error"):
|
||||
error["msg"] = ctx["error"].args[0]
|
||||
else:
|
||||
error["msg"] = custom_message.format(**ctx)
|
||||
else:
|
||||
error["msg"] = custom_message
|
||||
|
||||
# If the input value is a dictionary or if the input value is in the
|
||||
# error message, remove it
|
||||
if isinstance(error["input"], dict) or error["input"] in error["msg"]:
|
||||
error["input"] = None
|
||||
if error["input"] is not None:
|
||||
# If the input value is a dictionary, remove it
|
||||
if isinstance(error["input"], dict):
|
||||
error["input"] = None
|
||||
elif isinstance(error["input"], (float, int, bool, str)):
|
||||
# Or if the input value is in the error message, remove it
|
||||
input_value = str(error["input"])
|
||||
if input_value in error["msg"]:
|
||||
error["input"] = None
|
||||
|
||||
new_errors.append(error)
|
||||
|
||||
# Create a custom error message for RenderCV users
|
||||
for error in new_errors:
|
||||
location = ".".join(error["loc"])
|
||||
error_messages.append(f"{location}:\n {error['msg']}")
|
||||
if len(error["loc"]) > 0:
|
||||
location = ".".join(error["loc"])
|
||||
error_messages.append(f"{location}:\n {error['msg']}")
|
||||
else:
|
||||
error_messages.append(f"{error['msg']}")
|
||||
|
||||
if error["input"]:
|
||||
error_messages[-1] += f"\n Your input was \"{error['input']}\""
|
||||
error_message = "\n\n ".join(error_messages)
|
||||
|
|
|
@ -65,6 +65,7 @@ dictionary = [
|
|||
"javascript",
|
||||
]
|
||||
spell = SpellChecker()
|
||||
all_misspelled_words = set()
|
||||
|
||||
|
||||
def check_spelling(sentence: str) -> str:
|
||||
|
@ -110,10 +111,7 @@ def check_spelling(sentence: str) -> str:
|
|||
if word in dictionary:
|
||||
continue
|
||||
|
||||
logger.warning(
|
||||
f'The word "{word}" might be misspelled according to the'
|
||||
" pyspellchecker."
|
||||
)
|
||||
all_misspelled_words.add(word)
|
||||
|
||||
return sentence
|
||||
|
||||
|
@ -1232,6 +1230,35 @@ class CurriculumVitae(BaseModel):
|
|||
|
||||
return model
|
||||
|
||||
@model_validator(mode="after")
|
||||
@classmethod
|
||||
def print_all_the_misspeled_words(cls, model):
|
||||
"""Print all the words that are misspelled according to pyspellchecker."""
|
||||
if len(all_misspelled_words) > 0:
|
||||
messages = []
|
||||
messages.append(
|
||||
"The following words might be misspelled (according to pyspellchecker):"
|
||||
)
|
||||
|
||||
misspelled_words = list(all_misspelled_words)
|
||||
|
||||
# Make misspeled_words a list of lists where each list contains 5:
|
||||
misspelled_words = [
|
||||
misspelled_words[i : i + 5] for i in range(0, len(misspelled_words), 5)
|
||||
]
|
||||
|
||||
# Join the words in each list with a comma, and join the lists with a new
|
||||
# line:
|
||||
misspelled_words = "\n ".join(
|
||||
[", ".join(words) for words in misspelled_words]
|
||||
)
|
||||
messages.append(f" {misspelled_words}")
|
||||
|
||||
# Print the messages:
|
||||
logger.warning("\n".join(messages))
|
||||
|
||||
return model
|
||||
|
||||
@computed_field
|
||||
@cached_property
|
||||
def connections(self) -> list[Connection]:
|
||||
|
@ -1328,6 +1355,10 @@ class CurriculumVitae(BaseModel):
|
|||
link_text = custom_section.link_text
|
||||
entries = custom_section.entries
|
||||
break
|
||||
else:
|
||||
entry_type = None
|
||||
link_text = None
|
||||
entries = None
|
||||
|
||||
if entry_type is None or entries is None:
|
||||
raise ValueError(
|
||||
|
@ -1396,10 +1427,15 @@ class RenderCVDataModel(BaseModel):
|
|||
section_titles = [section.title for section in cv.sections]
|
||||
for title in design.options.show_timespan_in: # type: ignore
|
||||
if title not in section_titles:
|
||||
not_used_section_titles = list(
|
||||
set(section_titles) - set(design.options.show_timespan_in)
|
||||
)
|
||||
not_used_section_titles = ", ".join(not_used_section_titles)
|
||||
raise ValueError(
|
||||
f'The section "{title}" that is specified in the'
|
||||
' "show_timespan_in" option is not found in the CV 😱! The'
|
||||
f" available section titles are: {section_titles}"
|
||||
' "show_timespan_in" option is not found in the CV 😱 You'
|
||||
" might have wanted to use one of these:"
|
||||
f" {not_used_section_titles}"
|
||||
)
|
||||
|
||||
return model
|
||||
|
|
Loading…
Reference in New Issue