Skip to content

Commit f82c56f

Browse files
authored
Merge pull request #27 from pntech-dev/hotfix
fix(profile): harden null-safe profile parsing and update release notes
2 parents 436ecd0 + 1f9323b commit f82c56f

6 files changed

Lines changed: 47 additions & 18 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ Allows authorized users to create, edit, and manage document pages. Support for
3535

3636
---
3737

38-
## 🛠 What's New (v0.2.18)
38+
## 🛠 What's New (v0.2.19)
3939

40-
- Fixed an issue where selected Department or Category could occasionally lose visual highlight after collapsing and expanding sidebar groups.
41-
- Improved sidebar behavior so the previously selected item is restored more reliably after expanding a group.
40+
- Fixed a profile crash path where malformed user data could trigger `'NoneType' object has no attribute 'split'`.
41+
- Hardened profile data normalization so missing `username` values are safely handled as empty strings.
42+
- Improved profile update payload formatting to avoid extra spaces and unstable name parsing.
4243

4344
---
4445

README_RU.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@
3535

3636
---
3737

38-
## 🛠 Что нового (v0.2.18)
38+
## 🛠 Что нового (v0.2.19)
3939

40-
- Исправлена ошибка, из-за которой при сворачивании и разворачивании групп в боковой панели иногда визуально пропадала подсветка выбранного Отдела или Категории.
41-
- Улучшено поведение боковой панели: после разворачивания группы выбранный пункт теперь восстанавливается стабильнее.
40+
- Исправлен сценарий сбоя профиля, при котором некорректные данные пользователя могли приводить к ошибке `'NoneType' object has no attribute 'split'`.
41+
- Усилена нормализация данных профиля: при отсутствии `username` теперь безопасно используется пустая строка.
42+
- Улучшено формирование данных при сохранении профиля, чтобы избежать лишних пробелов и нестабильного разбора имени.
4243

4344
---
4445

modules/main/mvc/main_controller.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def _show_profile_dialog(self) -> None:
390390
return
391391

392392
try:
393-
user_data = self.model.get_full_user_data()
393+
user_data = self._sanitize_profile_user_data(self.model.get_full_user_data())
394394
if not user_data:
395395
logger.warning("Could not retrieve user data for profile.")
396396
return
@@ -423,6 +423,17 @@ def _show_profile_dialog(self) -> None:
423423
except Exception as e:
424424
self._handle_error(e, "Ошибка профиля")
425425

426+
@staticmethod
427+
def _sanitize_profile_user_data(user_data: dict | None) -> dict | None:
428+
"""Normalizes profile payload to prevent UI errors on malformed values."""
429+
if not isinstance(user_data, dict):
430+
return None
431+
432+
sanitized = dict(user_data)
433+
username = sanitized.get("username")
434+
sanitized["username"] = "" if username is None else str(username).strip()
435+
return sanitized
436+
426437

427438
def _on_profile_update_finished(self, new_data: dict):
428439
"""Handles successful profile update."""
@@ -1284,7 +1295,10 @@ def _handle_error(self, e: Exception, title: str = "Ошибка") -> None:
12841295
message="Срок действия сессии истек. Пожалуйста, войдите снова."
12851296
)
12861297
else:
1287-
logger.error(f"{title}: {e}")
1298+
logger.error(
1299+
f"{title}: {e}",
1300+
exc_info=(type(e), e, e.__traceback__)
1301+
)
12881302
msg = get_friendly_error_message(e)
12891303
NotificationService().show_toast(
12901304
notification_type="error",

modules/main/mvc/main_model.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,20 @@ def _normalize_user_data(data: dict | None) -> dict | None:
364364

365365
nested_user = data.get("user")
366366
if isinstance(nested_user, dict):
367-
return nested_user
367+
normalized = dict(nested_user)
368+
else:
369+
normalized = dict(data)
368370

369-
return data
371+
# Defensive normalization for UI code paths expecting string fields.
372+
# Keep payload shape unchanged: do not add new keys.
373+
if "username" in normalized:
374+
username = normalized.get("username")
375+
normalized["username"] = "" if username is None else str(username).strip()
376+
377+
if "department" in normalized and normalized.get("department") is None:
378+
normalized["department"] = ""
379+
380+
return normalized
370381

371382

372383
def _get_departments(self) -> list[dict]:

modules/profile/profile_dialog.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,12 @@ def _split_username(username) -> list[str]:
137137

138138
def get_updated_data(self) -> dict:
139139
"""Returns the updated user data from the form."""
140+
first_name = self.ui.firstname_lineEdit.text().strip()
141+
last_name = self.ui.lastname_lineEdit.text().strip()
142+
username = " ".join(part for part in (first_name, last_name) if part)
143+
140144
return {
141-
"username": " ".join([
142-
self.ui.firstname_lineEdit.text(),
143-
self.ui.lastname_lineEdit.text()
144-
]),
145+
"username": username,
145146
"department_id": self.ui.department_comboBox.currentData()
146147
}
147148

utils/whats_new_modal.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818

1919
RELEASE_NOTES = {
20-
"0.2.18": [
20+
"0.2.19": [
2121
{
22-
"title": "Стабильность выделения в боковой панели",
22+
"title": "Стабильность профиля",
2323
"items": [
24-
"Исправлена ошибка, из-за которой при сворачивании и разворачивании групп в боковой панели иногда визуально пропадала подсветка выбранного Отдела или Категории.",
25-
"После разворачивания группы выбранный пункт теперь восстанавливается стабильнее.",
24+
"Исправлен сценарий сбоя профиля при некорректном формате данных пользователя (ошибка вида: 'NoneType' object has no attribute 'split').",
25+
"Нормализация данных профиля усилена: отсутствующий username теперь безопасно обрабатывается как пустая строка.",
26+
"Формирование имени при сохранении профиля улучшено: лишние пробелы удаляются, чтобы избежать нестабильного разбора.",
2627
],
2728
},
2829
],

0 commit comments

Comments
 (0)