Coverage for src / local_deep_research / web / exceptions.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-25 01:07 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-25 01:07 +0000
1"""
2Custom exceptions for the web module.
4These exceptions are used to provide structured error handling
5that can be caught by Flask error handlers and converted to
6appropriate JSON responses.
7"""
9from typing import Any, Optional
12class WebAPIException(Exception):
13 """Base exception for all web API related errors."""
15 def __init__(
16 self,
17 message: str,
18 status_code: int = 500,
19 error_code: Optional[str] = None,
20 details: Optional[dict[str, Any]] = None,
21 ):
22 """
23 Initialize the web API exception.
25 Args:
26 message: Human-readable error message
27 status_code: HTTP status code for the error
28 error_code: Machine-readable error code for API consumers
29 details: Additional error details/context
30 """
31 super().__init__(message)
32 self.message = message
33 self.status_code = status_code
34 self.error_code = error_code or self.__class__.__name__
35 self.details = details or {}
37 def to_dict(self) -> dict[str, Any]:
38 """Convert exception to dictionary for JSON response."""
39 result = {
40 "status": "error",
41 "message": self.message,
42 "error_code": self.error_code,
43 }
44 if self.details:
45 result["details"] = self.details
46 return result
49class AuthenticationRequiredError(WebAPIException):
50 """Raised when authentication is required but not available."""
52 def __init__(
53 self,
54 message: str = "Authentication required: Please refresh the page and log in again.",
55 username: Optional[str] = None,
56 ):
57 details = {}
58 if username:
59 details["username"] = username
60 super().__init__(
61 message,
62 status_code=401,
63 error_code="AUTHENTICATION_REQUIRED",
64 details=details,
65 )