Catch integrity errors gracefully instead of dumping a giant stacktrace

This commit is contained in:
Jonas Linter
2025-11-27 14:47:05 +01:00
parent 454b524077
commit f89236228d

View File

@@ -1,21 +1,19 @@
"""Webhook processor interface and implementations."""
from abc import ABC, abstractmethod
import asyncio
from datetime import date, datetime
from typing import Any, Protocol
from fastapi import HTTPException, Request
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from alpine_bits_python.config_loader import get_advertising_account_ids
from alpine_bits_python.auth import generate_unique_id
from alpine_bits_python.config_loader import get_advertising_account_ids
from alpine_bits_python.customer_service import CustomerService
from alpine_bits_python.reservation_service import ReservationService
from alpine_bits_python.schemas import ReservationData
from .db import Hotel, WebhookRequest
from .logging_config import get_logger
@@ -52,6 +50,7 @@ class WebhookProcessorProtocol(Protocol):
Raises:
HTTPException on processing errors
"""
...
@@ -68,6 +67,7 @@ class WebhookProcessorRegistry:
Args:
processor: Processor instance to register
"""
self._processors[processor.webhook_type] = processor
_LOGGER.info("Registered webhook processor: %s", processor.webhook_type)
@@ -80,6 +80,7 @@ class WebhookProcessorRegistry:
Returns:
Processor instance or None if not found
"""
return self._processors.get(webhook_type)
@@ -252,9 +253,15 @@ async def process_wix_form_submission(request: Request, data: dict[str, Any], db
# Use ReservationService to create reservation
reservation_service = ReservationService(db)
db_reservation = await reservation_service.create_reservation(
reservation, db_customer.id
)
try:
db_reservation = await reservation_service.create_reservation(
reservation, db_customer.id
)
except IntegrityError as e:
_LOGGER.exception("Database integrity error creating reservation: %s", e)
raise HTTPException(
status_code=500, detail="Database error creating reservation"
) from e
async def push_event():
# Fire event for listeners (push, etc.) - hotel-specific dispatch
@@ -314,6 +321,7 @@ class WixFormProcessor:
Returns:
Response dict with status and details
"""
# Import here to avoid circular dependency
@@ -613,9 +621,8 @@ class GenericWebhookProcessor:
Returns:
Response dict with status and details
"""
# Call existing processing function
result = await process_generic_webhook_submission(request, payload, db_session)