
    LCj	                         d Z ddlmZmZ  G d de      Z G d de      Z G d de      Z G d	 d
e      Z G d de      Z	 G d de      Z
 G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zy)uo  
Custom exception hierarchy.

Why this matters in production: a raw Python exception (KeyError,
ValueError, AttributeError from deep inside a model) should NEVER reach
the client directly. It might leak file paths, internal variable names,
or stack traces — that's an information disclosure risk, and it's also
just a bad client experience.

Every exception here carries:
- a client-safe `message` (shown to the user)
- an internal `detail` (logged, never returned)
- an HTTP status code
- an error `code` (machine-readable, e.g. "MODEL_INFERENCE_FAILED") so
  the frontend can branch on it without parsing message text.
    )AnyOptionalc            
       j     e Zd ZU dZdZeed<   dZeed<   	 	 d
dede	e   de	e
eef      f fd	Z xZS )AppExceptionz1Base class for all application-raised exceptions.  status_codeINTERNAL_ERROR
error_codemessagedetailextrac                 ^    || _         |xs || _        |xs i | _        t        |   |       y )N)r   r   r   super__init__)selfr   r   r   	__class__s       @C:\Crop_Prediction\Backend\crop-ai-system\app\core\exceptions.pyr   zAppException.__init__   s0     '[b
!    )NN)__name__
__module____qualname____doc__r   int__annotations__r
   strr   dictr   r   __classcell__)r   s   @r   r   r      sY    ;K&J&
 !%*.		"	" 	" S#X'		" 	"r   r   c                       e Zd ZdZdZy)ValidationFailedErrori  VALIDATION_FAILEDNr   r   r   r   r
    r   r   r   r   '   s    K$Jr   r   c                       e Zd ZdZdZy)UnsupportedCropError  UNSUPPORTED_CROPNr!   r"   r   r   r$   r$   ,   s    K#Jr   r$   c                       e Zd ZdZdZy)UnsupportedDistrictErrorr%   UNSUPPORTED_DISTRICTNr!   r"   r   r   r(   r(   1   s    K'Jr   r(   c                       e Zd ZdZdZdZy)ModelNotLoadedErrorzJRaised when a required model file is missing or failed to load at startup.  MODEL_NOT_LOADEDNr   r   r   r   r   r
   r"   r   r   r+   r+   6   s    TK#Jr   r+   c                       e Zd ZdZdZdZy)ModelInferenceErrorzARaised when a model runs but produces an invalid/unusable result.r   MODEL_INFERENCE_FAILEDNr.   r"   r   r   r0   r0   <   s    KK)Jr   r0   c                       e Zd ZdZdZdZy)LLMServiceErrorz4Raised when the Claude API call fails after retries.i  LLM_SERVICE_UNAVAILABLENr.   r"   r   r   r3   r3   B   s    >K*Jr   r3   c                       e Zd ZdZdZdZy)CacheServiceErrorzGRaised when Redis is unreachable. Should degrade gracefully, not crash.r,   CACHE_UNAVAILABLENr.   r"   r   r   r6   r6   H   s    QK$Jr   r6   c                       e Zd ZdZdZy)TaskNotFoundErrori  TASK_NOT_FOUNDNr!   r"   r   r   r9   r9   N   s    K!Jr   r9   c                       e Zd ZdZdZy)TaskTimeoutErrori  TASK_TIMEOUTNr!   r"   r   r   r<   r<   S   s    KJr   r<   c                       e Zd ZdZdZy)RateLimitExceededErrori  RATE_LIMIT_EXCEEDEDNr!   r"   r   r   r?   r?   X   s    K&Jr   r?   c                       e Zd ZdZdZy)AuthenticationErrori  AUTHENTICATION_FAILEDNr!   r"   r   r   rB   rB   ]   s    K(Jr   rB   N)r   typingr   r   	Exceptionr   r   r$   r(   r+   r0   r3   r6   r9   r<   r?   rB   r"   r   r   <module>rF      s   " !"9 "$%L %
$< $
(| (
$, $*, *+l +% %" "
 |  
'\ '
), )r   