fix: use custom exceptions in onboarding and add tests
- Create onboarding-specific exceptions (OnboardingNotFoundException, etc.) - Remove HTTPException usage from API endpoints per architecture rules - Let exceptions propagate to global handler - Add 12 integration tests for onboarding API endpoints 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -252,6 +252,17 @@ from .vendor_theme import (
|
||||
VendorThemeNotFoundException,
|
||||
)
|
||||
|
||||
# Onboarding exceptions
|
||||
from .onboarding import (
|
||||
LetzshopConnectionFailedException,
|
||||
OnboardingAlreadyCompletedException,
|
||||
OnboardingCsvUrlRequiredException,
|
||||
OnboardingNotFoundException,
|
||||
OnboardingStepOrderException,
|
||||
OnboardingSyncJobNotFoundException,
|
||||
OnboardingSyncNotCompleteException,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
# Base exceptions
|
||||
"WizamartException",
|
||||
@@ -437,4 +448,12 @@ __all__ = [
|
||||
"SubscriptionAlreadyCancelledException",
|
||||
"InvalidWebhookSignatureException",
|
||||
"WebhookMissingSignatureException",
|
||||
# Onboarding exceptions
|
||||
"OnboardingNotFoundException",
|
||||
"OnboardingStepOrderException",
|
||||
"OnboardingAlreadyCompletedException",
|
||||
"LetzshopConnectionFailedException",
|
||||
"OnboardingCsvUrlRequiredException",
|
||||
"OnboardingSyncJobNotFoundException",
|
||||
"OnboardingSyncNotCompleteException",
|
||||
]
|
||||
|
||||
87
app/exceptions/onboarding.py
Normal file
87
app/exceptions/onboarding.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# app/exceptions/onboarding.py
|
||||
"""
|
||||
Onboarding-specific exceptions.
|
||||
|
||||
Exceptions for the vendor onboarding wizard flow.
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from .base import BusinessLogicException, ResourceNotFoundException, ValidationException
|
||||
|
||||
|
||||
class OnboardingNotFoundException(ResourceNotFoundException):
|
||||
"""Raised when onboarding record is not found for a vendor."""
|
||||
|
||||
def __init__(self, vendor_id: int):
|
||||
super().__init__(
|
||||
resource_type="VendorOnboarding",
|
||||
identifier=str(vendor_id),
|
||||
)
|
||||
|
||||
|
||||
class OnboardingStepOrderException(ValidationException):
|
||||
"""Raised when trying to access a step out of order."""
|
||||
|
||||
def __init__(self, current_step: str, required_step: str):
|
||||
super().__init__(
|
||||
message=f"Please complete the {required_step} step first",
|
||||
field="step",
|
||||
details={
|
||||
"current_step": current_step,
|
||||
"required_step": required_step,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class OnboardingAlreadyCompletedException(BusinessLogicException):
|
||||
"""Raised when trying to modify a completed onboarding."""
|
||||
|
||||
def __init__(self, vendor_id: int):
|
||||
super().__init__(
|
||||
message="Onboarding has already been completed",
|
||||
error_code="ONBOARDING_ALREADY_COMPLETED",
|
||||
details={"vendor_id": vendor_id},
|
||||
)
|
||||
|
||||
|
||||
class LetzshopConnectionFailedException(BusinessLogicException):
|
||||
"""Raised when Letzshop API connection test fails."""
|
||||
|
||||
def __init__(self, error_message: str):
|
||||
super().__init__(
|
||||
message=f"Letzshop connection failed: {error_message}",
|
||||
error_code="LETZSHOP_CONNECTION_FAILED",
|
||||
details={"error": error_message},
|
||||
)
|
||||
|
||||
|
||||
class OnboardingCsvUrlRequiredException(ValidationException):
|
||||
"""Raised when no CSV URL is provided in product import step."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
message="At least one CSV URL must be provided",
|
||||
field="csv_url",
|
||||
)
|
||||
|
||||
|
||||
class OnboardingSyncJobNotFoundException(ResourceNotFoundException):
|
||||
"""Raised when sync job is not found."""
|
||||
|
||||
def __init__(self, job_id: int):
|
||||
super().__init__(
|
||||
resource_type="LetzshopHistoricalImportJob",
|
||||
identifier=str(job_id),
|
||||
)
|
||||
|
||||
|
||||
class OnboardingSyncNotCompleteException(BusinessLogicException):
|
||||
"""Raised when trying to complete onboarding before sync is done."""
|
||||
|
||||
def __init__(self, job_status: str):
|
||||
super().__init__(
|
||||
message=f"Import job is still {job_status}, please wait",
|
||||
error_code="SYNC_NOT_COMPLETE",
|
||||
details={"job_status": job_status},
|
||||
)
|
||||
Reference in New Issue
Block a user