64 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import logging
import yaml
from typing import Optional, Dict # Для Python < 3.9 используйте Dict, для Python 3.9+ можно просто dict
logger = logging.getLogger(__name__)
class ConfigError(Exception):
"""Базовый класс для ошибок конфигурации."""
pass
class ConfigNotFoundError(ConfigError):
"""Файл конфигурации не найден."""
pass
class InvalidConfigFormatError(ConfigError):
"""Ошибка формата YAML в конфигурации."""
pass
def load_config(path: str) -> Optional[Dict]:
"""
Загрузка конфигурации из YAML файла.
Обрабатывает ошибки чтения файла и парсинга YAML.
:param path: Путь к файлу конфигурации.
:return: Словарь с конфигурацией или None в случае ошибки.
"""
logger.debug(f"Попытка загрузки конфигурации из файла: `{path}`")
try:
with open(path, "r", encoding="utf-8") as f:
config_data = yaml.safe_load(f)
# Проверим, что YAML действительно распарсился в словарь
if not isinstance(config_data, dict):
msg = f"Содержимое файла конфигурации `{path}` не является словарем. Тип: {type(config_data).__name__}."
logger.error(msg)
raise InvalidConfigFormatError(msg)
logger.info(msg=f"Конфигурация успешно загружена из `{path}`")
return config_data
except FileNotFoundError:
msg=f"Файл конфигурации не найден: `{path}`"
logger.error(msg)
raise ConfigNotFoundError(msg) from None # from None подавляет цепочку исключений
except yaml.YAMLError as e:
# YAMLError - базовый класс для ошибок PyYAML (ошибки сканера, парсера и т.п.)
msg = f"Ошибка парсинга YAML в файле `{path}`: {e}"
logger.error(msg)
raise InvalidConfigFormatError(msg) from e
except IOError as e:
# IOError или OSError для других проблем с доступом к файлу (например, права доступа)
msg = f"Ошибка ввода-вывода при чтении файла `{path}`: {e}"
logger.error(msg)
raise ConfigError(msg) from e # Общее исключение для других ошибок ввода-вывода
except Exception as e:
# Отлавливаем любые другие непредвиденные исключения
logger.critical(
msg=f"Непредвиденная ошибка при загрузке конфигурации из `{path}`: {e}",
exc_info=True # Добавляет трассировку стека в лог для лучшей диагностики
)
raise ConfigError(f"Непредвиденная ошибка: {e}") from e