Main exception renamed to WizamartException

This commit is contained in:
2025-10-27 21:55:05 +01:00
parent 1e0cbf5927
commit 5c80ba17c5
15 changed files with 126 additions and 179 deletions

View File

@@ -9,30 +9,20 @@ These endpoints allow admins to:
- Reset themes to default
All operations use the service layer for business logic.
All exceptions are handled by the global exception handler.
"""
import logging
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Path, status
from fastapi import APIRouter, Depends, Path
from sqlalchemy.orm import Session
from app.api.deps import get_current_admin_user, get_db
from app.services.vendor_theme_service import vendor_theme_service
from app.exceptions.vendor import VendorNotFoundException
from app.exceptions.vendor_theme import (
VendorThemeNotFoundException,
ThemePresetNotFoundException,
ThemeValidationException,
ThemeOperationException,
InvalidColorFormatException,
InvalidFontFamilyException
)
from models.database.user import User
from models.schema.vendor_theme import (
VendorThemeResponse,
VendorThemeUpdate,
ThemePresetResponse,
ThemePresetListResponse
)
@@ -61,16 +51,8 @@ async def get_theme_presets(
"""
logger.info("Getting theme presets")
try:
presets = vendor_theme_service.get_available_presets()
return {"presets": presets}
except Exception as e:
logger.error(f"Failed to get theme presets: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to retrieve theme presets"
)
presets = vendor_theme_service.get_available_presets()
return {"presets": presets}
# ============================================================================
@@ -97,27 +79,14 @@ async def get_vendor_theme(
- Complete theme configuration including colors, fonts, layout, and branding
**Errors:**
- `404`: Vendor not found
- `500`: Internal server error
- `404`: Vendor not found (VendorNotFoundException)
"""
logger.info(f"Getting theme for vendor: {vendor_code}")
try:
theme = vendor_theme_service.get_theme(db, vendor_code)
return theme
except VendorNotFoundException:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Vendor '{vendor_code}' not found"
)
except Exception as e:
logger.error(f"Failed to get theme for vendor {vendor_code}: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to retrieve theme"
)
# Service raises VendorNotFoundException if vendor not found
# Global exception handler converts it to HTTP 404
theme = vendor_theme_service.get_theme(db, vendor_code)
return theme
# ============================================================================
@@ -155,40 +124,16 @@ async def update_vendor_theme(
- Updated theme configuration
**Errors:**
- `404`: Vendor not found
- `422`: Validation error (invalid colors, fonts, or layout values)
- `500`: Internal server error
- `404`: Vendor not found (VendorNotFoundException)
- `422`: Validation error (ThemeValidationException, InvalidColorFormatException, etc.)
- `500`: Operation failed (ThemeOperationException)
"""
logger.info(f"Updating theme for vendor: {vendor_code}")
try:
theme = vendor_theme_service.update_theme(db, vendor_code, theme_data)
return theme.to_dict()
except VendorNotFoundException:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Vendor '{vendor_code}' not found"
)
except (ThemeValidationException, InvalidColorFormatException, InvalidFontFamilyException) as e:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=e.message
)
except ThemeOperationException as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e.message
)
except Exception as e:
logger.error(f"Failed to update theme for vendor {vendor_code}: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update theme"
)
# Service handles all validation and raises appropriate exceptions
# Global exception handler converts them to proper HTTP responses
theme = vendor_theme_service.update_theme(db, vendor_code, theme_data)
return theme.to_dict()
# ============================================================================
@@ -227,43 +172,20 @@ async def apply_theme_preset(
- Success message and applied theme configuration
**Errors:**
- `404`: Vendor or preset not found
- `500`: Internal server error
- `404`: Vendor not found (VendorNotFoundException) or preset not found (ThemePresetNotFoundException)
- `500`: Operation failed (ThemeOperationException)
"""
logger.info(f"Applying preset '{preset_name}' to vendor {vendor_code}")
try:
theme = vendor_theme_service.apply_theme_preset(db, vendor_code, preset_name)
# Service validates preset name and applies it
# Raises ThemePresetNotFoundException if preset doesn't exist
# Global exception handler converts to HTTP 404
theme = vendor_theme_service.apply_theme_preset(db, vendor_code, preset_name)
return {
"message": f"Applied {preset_name} preset successfully",
"theme": theme.to_dict()
}
except VendorNotFoundException:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Vendor '{vendor_code}' not found"
)
except ThemePresetNotFoundException as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=e.message
)
except ThemeOperationException as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e.message
)
except Exception as e:
logger.error(f"Failed to apply preset to vendor {vendor_code}: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to apply preset"
)
return {
"message": f"Applied {preset_name} preset successfully",
"theme": theme.to_dict()
}
# ============================================================================
@@ -291,36 +213,12 @@ async def delete_vendor_theme(
- Success message
**Errors:**
- `404`: Vendor not found or vendor has no custom theme
- `500`: Internal server error
- `404`: Vendor not found (VendorNotFoundException) or no custom theme (VendorThemeNotFoundException)
- `500`: Operation failed (ThemeOperationException)
"""
logger.info(f"Deleting theme for vendor: {vendor_code}")
try:
result = vendor_theme_service.delete_theme(db, vendor_code)
return result
except VendorNotFoundException:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Vendor '{vendor_code}' not found"
)
except VendorThemeNotFoundException:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Vendor '{vendor_code}' has no custom theme"
)
except ThemeOperationException as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e.message
)
except Exception as e:
logger.error(f"Failed to delete theme for vendor {vendor_code}: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to delete theme"
)
# Service handles deletion and raises exceptions if needed
# Global exception handler converts them to proper HTTP responses
result = vendor_theme_service.delete_theme(db, vendor_code)
return result

View File

@@ -6,14 +6,14 @@ Vendor management endpoints for admin.
import logging
from typing import Optional
from fastapi import APIRouter, Depends, Query, Path, HTTPException, Body
from fastapi import APIRouter, Depends, Query, Path, Body
from sqlalchemy.orm import Session
from app.api.deps import get_current_admin_user
from app.core.database import get_db
from app.services.admin_service import admin_service
from app.services.stats_service import stats_service
from app.exceptions import VendorNotFoundException
from app.exceptions import VendorNotFoundException, ConfirmationRequiredException
from models.schema.stats import VendorStatsResponse
from models.schema.vendor import (
VendorListResponse,
@@ -432,12 +432,13 @@ def delete_vendor(
Requires confirmation parameter: `confirm=true`
"""
# Raise custom exception instead of HTTPException
if not confirm:
raise HTTPException(
status_code=400,
detail="Deletion requires confirmation parameter: confirm=true"
raise ConfirmationRequiredException(
operation="delete_vendor",
message="Deletion requires confirmation parameter: confirm=true"
)
vendor = _get_vendor_by_identifier(db, vendor_identifier)
message = admin_service.delete_vendor(db, vendor.id)
return {"message": message}
return {"message": message}