-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathexceptions.py
More file actions
138 lines (108 loc) · 3.95 KB
/
exceptions.py
File metadata and controls
138 lines (108 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""Custom exceptions for fiddler_utils package.
This module defines a hierarchy of exceptions for better error handling
and more informative error messages.
"""
from typing import List, Optional
class FiddlerUtilsError(Exception):
"""Base exception for all fiddler_utils errors."""
pass
class ConnectionError(FiddlerUtilsError):
"""Raised when there are issues connecting to Fiddler."""
def __init__(self, message: str, url: Optional[str] = None):
self.url = url
super().__init__(message)
class ValidationError(FiddlerUtilsError):
"""Raised when validation fails (schema, FQL, assets, etc.)."""
def __init__(
self,
message: str,
errors: Optional[List[str]] = None,
field: Optional[str] = None,
):
self.errors = errors or []
self.field = field
full_message = message
if self.errors:
full_message += f'\nErrors: {", ".join(self.errors)}'
super().__init__(full_message)
class SchemaValidationError(ValidationError):
"""Raised when schema validation fails."""
def __init__(
self,
message: str,
missing_columns: Optional[List[str]] = None,
incompatible_types: Optional[List[str]] = None,
):
self.missing_columns = missing_columns or []
self.incompatible_types = incompatible_types or []
errors = []
if self.missing_columns:
errors.append(f'Missing columns: {", ".join(self.missing_columns)}')
if self.incompatible_types:
errors.append(f'Incompatible types: {", ".join(self.incompatible_types)}')
super().__init__(message, errors=errors)
class FQLError(ValidationError):
"""Raised when FQL expression validation or parsing fails."""
def __init__(
self,
message: str,
expression: Optional[str] = None,
position: Optional[int] = None,
):
self.expression = expression
self.position = position
full_message = message
if expression:
full_message += f'\nExpression: {expression}'
if position is not None:
full_message += f'\nPosition: {position}'
super().__init__(full_message)
class AssetNotFoundError(FiddlerUtilsError):
"""Raised when an asset (model, segment, metric, etc.) is not found."""
def __init__(
self,
message: str,
asset_type: Optional[str] = None,
asset_id: Optional[str] = None,
):
self.asset_type = asset_type
self.asset_id = asset_id
full_message = message
if asset_type:
full_message = f'{asset_type} not found: {message}'
super().__init__(full_message)
class AssetImportError(FiddlerUtilsError):
"""Raised when asset import fails."""
def __init__(
self,
message: str,
asset_name: Optional[str] = None,
reason: Optional[str] = None,
):
self.asset_name = asset_name
self.reason = reason
full_message = message
if asset_name:
full_message = f"Failed to import '{asset_name}': {message}"
if reason:
full_message += f' ({reason})'
super().__init__(full_message)
class BulkOperationError(FiddlerUtilsError):
"""Raised when bulk operations encounter errors."""
def __init__(
self,
message: str,
successful_count: int = 0,
failed_count: int = 0,
errors: Optional[List[tuple]] = None,
):
self.successful_count = successful_count
self.failed_count = failed_count
self.errors = errors or [] # List of (item, error_message) tuples
full_message = f'{message}\n'
full_message += f'Successful: {successful_count}, Failed: {failed_count}'
if self.errors:
full_message += f'\nFirst few errors:\n'
for item, error in self.errors[:5]:
full_message += f' - {item}: {error}\n'
super().__init__(full_message)