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

1""" 

2Custom exceptions for the web module. 

3 

4These exceptions are used to provide structured error handling 

5that can be caught by Flask error handlers and converted to 

6appropriate JSON responses. 

7""" 

8 

9from typing import Any, Optional 

10 

11 

12class WebAPIException(Exception): 

13 """Base exception for all web API related errors.""" 

14 

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. 

24 

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 {} 

36 

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 

47 

48 

49class AuthenticationRequiredError(WebAPIException): 

50 """Raised when authentication is required but not available.""" 

51 

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 )