| 12 | |
| 13 | @dataclass |
| 14 | class AppError: |
| 15 | code: str |
| 16 | title: str |
| 17 | detail: str |
| 18 | suggestion: str |
| 19 | status: int = 500 |
| 20 | retryable: bool = False |
| 21 | diagnostics: Dict[str, Any] = field(default_factory=dict) |
| 22 | |
| 23 | @property |
| 24 | def type(self) -> str: |
| 25 | return f"{ERROR_TYPE_BASE}/{self.code.lower().replace('_', '-')}" |
| 26 | |
| 27 | def to_dict(self) -> Dict[str, Any]: |
| 28 | return { |
| 29 | "type": self.type, |
| 30 | "code": self.code, |
| 31 | "title": self.title, |
| 32 | "detail": self.detail, |
| 33 | "suggestion": self.suggestion, |
| 34 | "status": self.status, |
| 35 | "retryable": self.retryable, |
| 36 | "diagnostics": self.diagnostics, |
| 37 | } |
| 38 | |
| 39 | def to_message(self) -> str: |
| 40 | if self.suggestion: |
| 41 | return f"{self.title}:{self.suggestion}" |
| 42 | return f"{self.title}:{self.detail}" |
| 43 | |
| 44 | |
| 45 | def error_payload(error: Union[AppError, Exception, str], context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: |
no outgoing calls
no test coverage detected