Coverage for netrun_errors \ base.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-25 19:24 -0800

1""" 

2Base exception class for Netrun Systems unified error handling. 

3 

4Provides structured error responses with correlation IDs, timestamps, 

5and machine-readable error codes for FastAPI applications. 

6""" 

7 

8from datetime import datetime, timezone 

9from typing import Any, Dict, Optional 

10from uuid import uuid4 

11 

12from fastapi import HTTPException, status 

13 

14 

15class NetrunException(HTTPException): 

16 """ 

17 Base exception class for all Netrun Systems exceptions. 

18 

19 Extends FastAPI's HTTPException with additional metadata: 

20 - error_code: Machine-readable error identifier 

21 - correlation_id: Request tracking identifier 

22 - timestamp: ISO 8601 formatted timestamp 

23 - details: Additional context dictionary 

24 

25 All Netrun exceptions inherit from this class and return structured 

26 JSON responses compatible with frontend error handling. 

27 """ 

28 

29 def __init__( 

30 self, 

31 status_code: int, 

32 error_code: str, 

33 message: str, 

34 details: Optional[Dict[str, Any]] = None, 

35 correlation_id: Optional[str] = None, 

36 ): 

37 """ 

38 Initialize NetrunException with structured error data. 

39 

40 Args: 

41 status_code: HTTP status code (401, 403, 404, etc.) 

42 error_code: Machine-readable error code (e.g., "AUTH_INVALID_CREDENTIALS") 

43 message: Human-readable error message 

44 details: Additional context dictionary (optional) 

45 correlation_id: Request tracking ID (auto-generated if not provided) 

46 """ 

47 self.error_code = error_code 

48 self.message = message 

49 self.correlation_id = correlation_id or self._generate_correlation_id() 

50 self.timestamp = datetime.now(timezone.utc).isoformat() 

51 self.details = details or {} 

52 

53 # Store message as detail for HTTPException (plain string) 

54 super().__init__(status_code=status_code, detail=message) 

55 

56 @staticmethod 

57 def _generate_correlation_id() -> str: 

58 """ 

59 Generate a unique correlation ID for request tracking. 

60 

61 Format: req-YYYYMMDD-HHMMSS-uuid4_prefix 

62 Example: req-20251125-143210-a8f3c9 

63 

64 Returns: 

65 Correlation ID string 

66 """ 

67 timestamp = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S") 

68 uuid_prefix = str(uuid4())[:6] 

69 return f"req-{timestamp}-{uuid_prefix}" 

70 

71 def to_dict(self) -> Dict[str, Any]: 

72 """ 

73 Convert exception to dictionary representation. 

74 

75 Returns: 

76 Dictionary with error structure 

77 """ 

78 return { 

79 "error": { 

80 "code": self.error_code, 

81 "message": self.message, 

82 "details": self.details, 

83 "correlation_id": self.correlation_id, 

84 "timestamp": self.timestamp, 

85 } 

86 }