style: apply black and isort formatting across entire codebase
- Standardize quote style (single to double quotes) - Reorder and group imports alphabetically - Fix line breaks and indentation for consistency - Apply PEP 8 formatting standards Also updated Makefile to exclude both venv and .venv from code quality checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,13 +13,14 @@ This module provides classes and functions for:
|
||||
import logging
|
||||
from typing import Union
|
||||
|
||||
from fastapi import Request, HTTPException
|
||||
from fastapi import HTTPException, Request
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse, RedirectResponse
|
||||
|
||||
from middleware.context import RequestContext, get_request_context
|
||||
|
||||
from .base import WizamartException
|
||||
from .error_renderer import ErrorPageRenderer
|
||||
from middleware.context import RequestContext, get_request_context
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -38,8 +39,8 @@ def setup_exception_handlers(app):
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"accept": request.headers.get("accept", ""),
|
||||
"method": request.method
|
||||
}
|
||||
"method": request.method,
|
||||
},
|
||||
)
|
||||
|
||||
# Redirect to appropriate login page based on context
|
||||
@@ -56,15 +57,12 @@ def setup_exception_handlers(app):
|
||||
"url": str(request.url),
|
||||
"method": request.method,
|
||||
"exception_type": type(exc).__name__,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an API request
|
||||
if _is_api_request(request):
|
||||
return JSONResponse(
|
||||
status_code=exc.status_code,
|
||||
content=exc.to_dict()
|
||||
)
|
||||
return JSONResponse(status_code=exc.status_code, content=exc.to_dict())
|
||||
|
||||
# Check if this is an HTML page request
|
||||
if _is_html_page_request(request):
|
||||
@@ -78,10 +76,7 @@ def setup_exception_handlers(app):
|
||||
)
|
||||
|
||||
# Default to JSON for unknown request types
|
||||
return JSONResponse(
|
||||
status_code=exc.status_code,
|
||||
content=exc.to_dict()
|
||||
)
|
||||
return JSONResponse(status_code=exc.status_code, content=exc.to_dict())
|
||||
|
||||
@app.exception_handler(HTTPException)
|
||||
async def http_exception_handler(request: Request, exc: HTTPException):
|
||||
@@ -96,7 +91,7 @@ def setup_exception_handlers(app):
|
||||
"url": str(request.url),
|
||||
"method": request.method,
|
||||
"exception_type": "HTTPException",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an API request
|
||||
@@ -107,7 +102,7 @@ def setup_exception_handlers(app):
|
||||
"error_code": f"HTTP_{exc.status_code}",
|
||||
"message": exc.detail,
|
||||
"status_code": exc.status_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an HTML page request
|
||||
@@ -128,11 +123,13 @@ def setup_exception_handlers(app):
|
||||
"error_code": f"HTTP_{exc.status_code}",
|
||||
"message": exc.detail,
|
||||
"status_code": exc.status_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@app.exception_handler(RequestValidationError)
|
||||
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
||||
async def validation_exception_handler(
|
||||
request: Request, exc: RequestValidationError
|
||||
):
|
||||
"""Handle Pydantic validation errors with consistent format."""
|
||||
|
||||
# Sanitize errors to remove sensitive data from logs
|
||||
@@ -140,8 +137,8 @@ def setup_exception_handlers(app):
|
||||
for error in exc.errors():
|
||||
sanitized_error = error.copy()
|
||||
# Remove 'input' field which may contain passwords
|
||||
if 'input' in sanitized_error:
|
||||
sanitized_error['input'] = '<redacted>'
|
||||
if "input" in sanitized_error:
|
||||
sanitized_error["input"] = "<redacted>"
|
||||
sanitized_errors.append(sanitized_error)
|
||||
|
||||
logger.error(
|
||||
@@ -151,7 +148,7 @@ def setup_exception_handlers(app):
|
||||
"url": str(request.url),
|
||||
"method": request.method,
|
||||
"exception_type": "RequestValidationError",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Clean up validation errors to ensure JSON serializability
|
||||
@@ -159,15 +156,17 @@ def setup_exception_handlers(app):
|
||||
for error in exc.errors():
|
||||
clean_error = {}
|
||||
for key, value in error.items():
|
||||
if key == 'input' and isinstance(value, bytes):
|
||||
if key == "input" and isinstance(value, bytes):
|
||||
# Convert bytes to string representation for JSON serialization
|
||||
clean_error[key] = f"<bytes: {len(value)} bytes>"
|
||||
elif key == 'ctx' and isinstance(value, dict):
|
||||
elif key == "ctx" and isinstance(value, dict):
|
||||
# Handle the 'ctx' field that contains ValueError objects
|
||||
clean_ctx = {}
|
||||
for ctx_key, ctx_value in value.items():
|
||||
if isinstance(ctx_value, Exception):
|
||||
clean_ctx[ctx_key] = str(ctx_value) # Convert exception to string
|
||||
clean_ctx[ctx_key] = str(
|
||||
ctx_value
|
||||
) # Convert exception to string
|
||||
else:
|
||||
clean_ctx[ctx_key] = ctx_value
|
||||
clean_error[key] = clean_ctx
|
||||
@@ -186,10 +185,8 @@ def setup_exception_handlers(app):
|
||||
"error_code": "VALIDATION_ERROR",
|
||||
"message": "Request validation failed",
|
||||
"status_code": 422,
|
||||
"details": {
|
||||
"validation_errors": clean_errors
|
||||
}
|
||||
}
|
||||
"details": {"validation_errors": clean_errors},
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an HTML page request
|
||||
@@ -210,10 +207,8 @@ def setup_exception_handlers(app):
|
||||
"error_code": "VALIDATION_ERROR",
|
||||
"message": "Request validation failed",
|
||||
"status_code": 422,
|
||||
"details": {
|
||||
"validation_errors": clean_errors
|
||||
}
|
||||
}
|
||||
"details": {"validation_errors": clean_errors},
|
||||
},
|
||||
)
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
@@ -227,7 +222,7 @@ def setup_exception_handlers(app):
|
||||
"url": str(request.url),
|
||||
"method": request.method,
|
||||
"exception_type": type(exc).__name__,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an API request
|
||||
@@ -238,7 +233,7 @@ def setup_exception_handlers(app):
|
||||
"error_code": "INTERNAL_SERVER_ERROR",
|
||||
"message": "Internal server error",
|
||||
"status_code": 500,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an HTML page request
|
||||
@@ -259,7 +254,7 @@ def setup_exception_handlers(app):
|
||||
"error_code": "INTERNAL_SERVER_ERROR",
|
||||
"message": "Internal server error",
|
||||
"status_code": 500,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@app.exception_handler(404)
|
||||
@@ -275,11 +270,8 @@ def setup_exception_handlers(app):
|
||||
"error_code": "ENDPOINT_NOT_FOUND",
|
||||
"message": f"Endpoint not found: {request.url.path}",
|
||||
"status_code": 404,
|
||||
"details": {
|
||||
"path": request.url.path,
|
||||
"method": request.method
|
||||
}
|
||||
}
|
||||
"details": {"path": request.url.path, "method": request.method},
|
||||
},
|
||||
)
|
||||
|
||||
# Check if this is an HTML page request
|
||||
@@ -300,11 +292,8 @@ def setup_exception_handlers(app):
|
||||
"error_code": "ENDPOINT_NOT_FOUND",
|
||||
"message": f"Endpoint not found: {request.url.path}",
|
||||
"status_code": 404,
|
||||
"details": {
|
||||
"path": request.url.path,
|
||||
"method": request.method
|
||||
}
|
||||
}
|
||||
"details": {"path": request.url.path, "method": request.method},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -332,8 +321,8 @@ def _is_html_page_request(request: Request) -> bool:
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"method": request.method,
|
||||
"accept": request.headers.get("accept", "")
|
||||
}
|
||||
"accept": request.headers.get("accept", ""),
|
||||
},
|
||||
)
|
||||
|
||||
# Don't redirect API calls
|
||||
@@ -354,7 +343,9 @@ def _is_html_page_request(request: Request) -> bool:
|
||||
# MUST explicitly accept HTML (strict check)
|
||||
accept_header = request.headers.get("accept", "")
|
||||
if "text/html" not in accept_header:
|
||||
logger.debug(f"Not HTML page: Accept header doesn't include text/html: {accept_header}")
|
||||
logger.debug(
|
||||
f"Not HTML page: Accept header doesn't include text/html: {accept_header}"
|
||||
)
|
||||
return False
|
||||
|
||||
logger.debug("IS HTML page request")
|
||||
@@ -379,13 +370,21 @@ def _redirect_to_login(request: Request) -> RedirectResponse:
|
||||
elif context_type == RequestContext.SHOP:
|
||||
# For shop context, redirect to shop login (customer login)
|
||||
# Calculate base_url for proper routing (supports domain, subdomain, and path-based access)
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
vendor_context = getattr(request.state, 'vendor_context', None)
|
||||
access_method = vendor_context.get('detection_method', 'unknown') if vendor_context else 'unknown'
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
vendor_context = getattr(request.state, "vendor_context", None)
|
||||
access_method = (
|
||||
vendor_context.get("detection_method", "unknown")
|
||||
if vendor_context
|
||||
else "unknown"
|
||||
)
|
||||
|
||||
base_url = "/"
|
||||
if access_method == "path" and vendor:
|
||||
full_prefix = vendor_context.get('full_prefix', '/vendor/') if vendor_context else '/vendor/'
|
||||
full_prefix = (
|
||||
vendor_context.get("full_prefix", "/vendor/")
|
||||
if vendor_context
|
||||
else "/vendor/"
|
||||
)
|
||||
base_url = f"{full_prefix}{vendor.subdomain}/"
|
||||
|
||||
login_url = f"{base_url}shop/account/login"
|
||||
@@ -401,22 +400,28 @@ def _redirect_to_login(request: Request) -> RedirectResponse:
|
||||
def raise_not_found(resource_type: str, identifier: str) -> None:
|
||||
"""Convenience function to raise ResourceNotFoundException."""
|
||||
from .base import ResourceNotFoundException
|
||||
|
||||
raise ResourceNotFoundException(resource_type, identifier)
|
||||
|
||||
|
||||
def raise_validation_error(message: str, field: str = None, details: dict = None) -> None:
|
||||
def raise_validation_error(
|
||||
message: str, field: str = None, details: dict = None
|
||||
) -> None:
|
||||
"""Convenience function to raise ValidationException."""
|
||||
from .base import ValidationException
|
||||
|
||||
raise ValidationException(message, field, details)
|
||||
|
||||
|
||||
def raise_auth_error(message: str = "Authentication failed") -> None:
|
||||
"""Convenience function to raise AuthenticationException."""
|
||||
from .base import AuthenticationException
|
||||
|
||||
raise AuthenticationException(message)
|
||||
|
||||
|
||||
def raise_permission_error(message: str = "Access denied") -> None:
|
||||
"""Convenience function to raise AuthorizationException."""
|
||||
from .base import AuthorizationException
|
||||
|
||||
raise AuthorizationException(message)
|
||||
|
||||
Reference in New Issue
Block a user