From 7adb397b1544724c76c288d445b394392705c1e2 Mon Sep 17 00:00:00 2001 From: m-xim <170838360+m-xim@users.noreply.github.com> Date: Sat, 10 May 2025 06:39:11 +0300 Subject: [PATCH 1/5] Add FluentMessageError for better error handling in fluent message processing --- examples/language_inline_markup.py | 4 ++-- src/aiogram_i18n/cores/fluent_compile_core.py | 4 ++-- src/aiogram_i18n/cores/fluent_runtime_core.py | 4 ++-- src/aiogram_i18n/exceptions.py | 12 ++++++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/examples/language_inline_markup.py b/examples/language_inline_markup.py index e068fde..afe039a 100644 --- a/examples/language_inline_markup.py +++ b/examples/language_inline_markup.py @@ -28,14 +28,14 @@ async def cmd_start(message: Message, i18n: I18nContext): @router.callback_query(F.data == "back") -async def btn_help(call: CallbackQuery, i18n: I18nContext): +async def btn_back(call: CallbackQuery, i18n: I18nContext): await call.message.edit_text( text=i18n.get("hello", user=call.from_user.full_name) ) @router.callback_query(lang_kb.filter) -async def btn_help(call: CallbackQuery, lang: str, i18n: I18nContext): +async def btn_lang(call: CallbackQuery, lang: str, i18n: I18nContext): await call.answer() await i18n.set_locale(locale=lang) await call.message.edit_text(text=i18n.cur.lang(language=i18n.locale)) diff --git a/src/aiogram_i18n/cores/fluent_compile_core.py b/src/aiogram_i18n/cores/fluent_compile_core.py index e6cadff..22af4cb 100644 --- a/src/aiogram_i18n/cores/fluent_compile_core.py +++ b/src/aiogram_i18n/cores/fluent_compile_core.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, cast -from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError +from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError, FluentMessageError from aiogram_i18n.utils.text_decorator import td try: @@ -44,7 +44,7 @@ def get(self, message: str, locale: str | None = None, /, **kwargs: Any) -> str: raise KeyNotFoundError(message) from None return message if errors: - raise errors[0] + raise FluentMessageError(message_id=message, errors=errors) return cast(str, text) # 'cause fluent_compiler type-ignored def find_locales(self) -> dict[str, FluentBundle]: diff --git a/src/aiogram_i18n/cores/fluent_runtime_core.py b/src/aiogram_i18n/cores/fluent_runtime_core.py index c9ef880..99a4d31 100644 --- a/src/aiogram_i18n/cores/fluent_runtime_core.py +++ b/src/aiogram_i18n/cores/fluent_runtime_core.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, cast -from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError +from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError, FluentMessageError from aiogram_i18n.utils.text_decorator import td try: @@ -49,7 +49,7 @@ def get(self, message_id: str, locale: str | None = None, /, **kwargs: Any) -> s return message_id text, errors = translator.format_pattern(pattern=message.value, args=kwargs) if errors: - raise errors[0] + raise FluentMessageError(message_id=message_id, errors=errors) return cast(str, text) def find_locales(self) -> dict[str, FluentBundle]: diff --git a/src/aiogram_i18n/exceptions.py b/src/aiogram_i18n/exceptions.py index 0a6417a..de62388 100644 --- a/src/aiogram_i18n/exceptions.py +++ b/src/aiogram_i18n/exceptions.py @@ -78,3 +78,15 @@ def __init__(self, locale: str) -> None: def __str__(self) -> str: return self.message.format(locale=self.locale) + + +class FluentMessageError(AiogramI18nError): + def __init__(self, message_id: str, errors: List[Exception]) -> None: + self.message_id = message_id + self.errors = errors + + def __str__(self) -> str: + lines = [f"\n{len(self.errors)} errors for message '{self.message_id}':"] + for idx, err in enumerate(self.errors, start=1): + lines.append(f" {err} (type={err.__class__.__name__})") + return "\n".join(lines) From 64a9b5052809bce451350e450ddffb57830fb77b Mon Sep 17 00:00:00 2001 From: m-xim <170838360+m-xim@users.noreply.github.com> Date: Sat, 10 May 2025 07:33:43 +0300 Subject: [PATCH 2/5] Fix text --- src/aiogram_i18n/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aiogram_i18n/exceptions.py b/src/aiogram_i18n/exceptions.py index de62388..07a1280 100644 --- a/src/aiogram_i18n/exceptions.py +++ b/src/aiogram_i18n/exceptions.py @@ -86,7 +86,7 @@ def __init__(self, message_id: str, errors: List[Exception]) -> None: self.errors = errors def __str__(self) -> str: - lines = [f"\n{len(self.errors)} errors for message '{self.message_id}':"] + lines = [f"\n{len(self.errors)} errors for key '{self.message_id}':"] for idx, err in enumerate(self.errors, start=1): lines.append(f" {err} (type={err.__class__.__name__})") return "\n".join(lines) From aaf7af2f1cc65d2055e4a1d9d62a2d3a508fd5b5 Mon Sep 17 00:00:00 2001 From: m-xim <170838360+m-xim@users.noreply.github.com> Date: Sat, 10 May 2025 07:57:31 +0300 Subject: [PATCH 3/5] Clean code --- src/aiogram_i18n/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aiogram_i18n/exceptions.py b/src/aiogram_i18n/exceptions.py index 07a1280..903d186 100644 --- a/src/aiogram_i18n/exceptions.py +++ b/src/aiogram_i18n/exceptions.py @@ -87,6 +87,6 @@ def __init__(self, message_id: str, errors: List[Exception]) -> None: def __str__(self) -> str: lines = [f"\n{len(self.errors)} errors for key '{self.message_id}':"] - for idx, err in enumerate(self.errors, start=1): + for err in self.errors: lines.append(f" {err} (type={err.__class__.__name__})") return "\n".join(lines) From d05376caa30b286bb79bbdae93b67273f145c7d4 Mon Sep 17 00:00:00 2001 From: m-xim <170838360+m-xim@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:22:14 +0300 Subject: [PATCH 4/5] refactor --- src/aiogram_i18n/cores/fluent_compile_core.py | 2 +- src/aiogram_i18n/cores/fluent_runtime_core.py | 2 +- src/aiogram_i18n/exceptions.py | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/aiogram_i18n/cores/fluent_compile_core.py b/src/aiogram_i18n/cores/fluent_compile_core.py index 22af4cb..8066e16 100644 --- a/src/aiogram_i18n/cores/fluent_compile_core.py +++ b/src/aiogram_i18n/cores/fluent_compile_core.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, cast -from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError, FluentMessageError +from aiogram_i18n.exceptions import FluentMessageError, KeyNotFoundError, NoModuleError from aiogram_i18n.utils.text_decorator import td try: diff --git a/src/aiogram_i18n/cores/fluent_runtime_core.py b/src/aiogram_i18n/cores/fluent_runtime_core.py index 99a4d31..290d7f2 100644 --- a/src/aiogram_i18n/cores/fluent_runtime_core.py +++ b/src/aiogram_i18n/cores/fluent_runtime_core.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, cast -from aiogram_i18n.exceptions import KeyNotFoundError, NoModuleError, FluentMessageError +from aiogram_i18n.exceptions import FluentMessageError, KeyNotFoundError, NoModuleError from aiogram_i18n.utils.text_decorator import td try: diff --git a/src/aiogram_i18n/exceptions.py b/src/aiogram_i18n/exceptions.py index 903d186..28cdc4c 100644 --- a/src/aiogram_i18n/exceptions.py +++ b/src/aiogram_i18n/exceptions.py @@ -81,12 +81,11 @@ def __str__(self) -> str: class FluentMessageError(AiogramI18nError): - def __init__(self, message_id: str, errors: List[Exception]) -> None: + def __init__(self, message_id: str, errors: list[Exception]) -> None: self.message_id = message_id self.errors = errors def __str__(self) -> str: lines = [f"\n{len(self.errors)} errors for key '{self.message_id}':"] - for err in self.errors: - lines.append(f" {err} (type={err.__class__.__name__})") + lines.extend(f" {err} (type={type(err).__name__})" for err in self.errors) return "\n".join(lines) From 9449a9d8f2c836e2e9b62bf7b8fc734337a304bc Mon Sep 17 00:00:00 2001 From: m-xim <170838360+m-xim@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:25:16 +0300 Subject: [PATCH 5/5] Update src/aiogram_i18n/exceptions.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/aiogram_i18n/exceptions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aiogram_i18n/exceptions.py b/src/aiogram_i18n/exceptions.py index 28cdc4c..78ceb72 100644 --- a/src/aiogram_i18n/exceptions.py +++ b/src/aiogram_i18n/exceptions.py @@ -86,6 +86,7 @@ def __init__(self, message_id: str, errors: list[Exception]) -> None: self.errors = errors def __str__(self) -> str: - lines = [f"\n{len(self.errors)} errors for key '{self.message_id}':"] + error_word = "error" if len(self.errors) == 1 else "errors" + lines = [f"\n{len(self.errors)} {error_word} for key '{self.message_id}':"] lines.extend(f" {err} (type={type(err).__name__})" for err in self.errors) return "\n".join(lines)