Email validation no longer breaks customer retrieval

This commit is contained in:
Jonas Linter
2025-10-14 08:46:16 +02:00
parent 0e659072c0
commit 99d1ed1732
2 changed files with 35 additions and 4 deletions

View File

@@ -1,9 +1,12 @@
import re
import traceback
from dataclasses import dataclass
from datetime import UTC
from enum import Enum
from typing import Any
from email_validator import EmailNotValidError, validate_email
from alpine_bits_python.db import Customer, Reservation
from alpine_bits_python.logging_config import get_logger
from alpine_bits_python.schemas import (
@@ -618,6 +621,34 @@ def create_res_notif_push_message(
return _create_xml_from_db(list, OtaMessageType.NOTIF, config)
def _validate_and_repair_email(email: str | None) -> str | None:
"""Validate and repair email addresses with common typos.
Attempts to fix trailing digits in TLDs (e.g., .de1 -> .de)
before validation. If the email is still invalid, returns None
instead of raising an exception.
Args:
email: Email address to validate and repair
Returns:
Normalized email address or None if invalid
"""
if email is None:
return None
# Remove trailing digits from TLD (e.g., .de1 -> .de, .com2 -> .com)
# This matches a dot followed by letters, then trailing digits at the end
email = re.sub(r'(\.[a-zA-Z]+)\d+$', r'\1', email)
try:
email_info = validate_email(email)
except EmailNotValidError as e:
_LOGGER.warning("invalid email address: %s", e)
return None
return email_info.normalized
def _process_single_reservation(
reservation: Reservation,
customer: Customer,

View File

@@ -13,7 +13,6 @@ from dataclasses import dataclass
from datetime import datetime
from enum import Enum, IntEnum
from typing import Any, Optional, override
from zoneinfo import ZoneInfo
from xsdata.formats.dataclass.serializers.config import SerializerConfig
from xsdata_pydantic.bindings import XmlParser, XmlSerializer
@@ -24,8 +23,7 @@ from alpine_bits_python.alpine_bits_helpers import (
)
from alpine_bits_python.logging_config import get_logger
from .db import AckedRequest, Customer, Reservation
from .reservation_service import ReservationService
from .db import Customer, Reservation
from .generated.alpinebits import (
OtaNotifReportRq,
OtaNotifReportRs,
@@ -34,6 +32,7 @@ from .generated.alpinebits import (
OtaReadRq,
WarningStatus,
)
from .reservation_service import ReservationService
# Configure logging
_LOGGER = get_logger(__name__)
@@ -147,7 +146,8 @@ class AlpineBitsResponse:
"""Validate that status code is one of the allowed values."""
if self.status_code not in [200, 400, 401, 500]:
raise ValueError(
f"Invalid status code {self.status_code}. Must be 200, 400, 401, or 500"
"Invalid status code %s. Must be 200, 400, 401, or 500",
self.status_code,
)