Skip to content

Commit 66fefef

Browse files
committed
vdk-core: create ingestion exceptions
Replacing generic exception names like DomainError, UserCodeError, , and PlatformServiceError with more domain-specific exceptions (in this case the domain being ingestion) can offer differnet benefits See #2682 VdkConfigurationError is not changed as it's pretty clear for now. I am wondering if it still might not be better ot have IngsetionConfigurationException but could not decide and omit it from this change.
1 parent 0b5a97b commit 66fefef

File tree

12 files changed

+410
-166
lines changed

12 files changed

+410
-166
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Copyright 2021-2023 VMware, Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
from typing import Any
4+
from typing import Optional
5+
6+
from vdk.internal.core.errors import BaseVdkError
7+
from vdk.internal.core.errors import ResolvableBy
8+
9+
10+
class IngestionException(BaseVdkError):
11+
"""
12+
Base Exception for all custom exceptions related to the ingestion process.
13+
This is intended to catch general exceptions that do not fit into more specific categories.
14+
"""
15+
16+
def __init__(self, message: str, resolvable_by: Optional[ResolvableBy] = None):
17+
super().__init__(None, resolvable_by, message)
18+
19+
20+
class PayloadIngestionException(IngestionException):
21+
"""
22+
Base Exception for all payload-related issues during the ingestion process.
23+
"""
24+
25+
def __init__(
26+
self,
27+
payload_id: str,
28+
message: str,
29+
destination_table: str = "",
30+
target: str = "",
31+
resolvable_by: Optional[ResolvableBy] = None,
32+
):
33+
"""
34+
:param payload_id: ID of the payload. This is a way for user to find out which payload failed to ingest.
35+
Left empty if such information is not available
36+
"""
37+
super().__init__(message=message, resolvable_by=resolvable_by)
38+
# we are purposefully are not putting payload id
39+
# in the message, so it's not logged in case it's sensitive
40+
self.payload_id = payload_id
41+
self.destination_table = destination_table
42+
self.target = target
43+
44+
45+
class EmptyPayloadIngestionException(PayloadIngestionException):
46+
"""
47+
Raised when an empty payload is encountered during ingestion and it is not expected.
48+
"""
49+
50+
def __init__(
51+
self,
52+
message: Optional[str] = None,
53+
resolvable_by: Optional[ResolvableBy] = None,
54+
):
55+
if not message:
56+
message = "Payload given to ingestion method should not be empty."
57+
super().__init__(payload_id="", message=message, resolvable_by=resolvable_by)
58+
59+
60+
class InvalidPayloadTypeIngestionException(PayloadIngestionException):
61+
"""
62+
Raised when the payload provided for ingestion has an invalid type.
63+
"""
64+
65+
def __init__(
66+
self,
67+
payload_id: str,
68+
expected_type: str,
69+
actual_type: str,
70+
message: Optional[str] = None,
71+
resolvable_by: Optional[ResolvableBy] = None,
72+
):
73+
"""
74+
:param expected_type: The expected type for the payload
75+
:param actual_type: The actual type of the payload
76+
"""
77+
if not message:
78+
message = "Invalid ingestion payload type."
79+
super().__init__(
80+
message=f"{message} Expected type: {expected_type}, actual type: {actual_type}.",
81+
payload_id=payload_id,
82+
resolvable_by=resolvable_by,
83+
)
84+
85+
86+
class JsonSerializationIngestionException(PayloadIngestionException):
87+
"""
88+
Raised when a payload is not JSON-serializable during ingestion.
89+
"""
90+
91+
def __init__(
92+
self,
93+
payload_id: str,
94+
original_exception: Exception,
95+
message: str = "",
96+
resolvable_by: Optional[ResolvableBy] = None,
97+
):
98+
"""
99+
:param original_exception: The original exception triggering this error
100+
"""
101+
if not message:
102+
message = "Payload is not json serializable."
103+
super().__init__(
104+
message=f"{message} Failure caused by {original_exception}",
105+
payload_id=payload_id,
106+
resolvable_by=resolvable_by,
107+
)
108+
109+
110+
class InvalidArgumentsIngestionException(IngestionException):
111+
"""
112+
Raised when an argument provided to a data ingestion method does not meet the expected constraints.
113+
"""
114+
115+
def __init__(
116+
self,
117+
param_name: str,
118+
param_constraint: str,
119+
actual_value: Any,
120+
message: str = "",
121+
resolvable_by: ResolvableBy = None,
122+
):
123+
"""
124+
:param param_name: The name of the parameter that caused the exception.
125+
:param param_constraint: Description of the constraint that the parameter failed to meet.
126+
:param actual_value: The actual value that was passed for the parameter.
127+
"""
128+
super().__init__(
129+
message=f"Ingestion parameter '{param_name}' is not valid. "
130+
f"It must match constraint {param_constraint} but was '{actual_value}'. "
131+
f"{message}",
132+
resolvable_by=resolvable_by,
133+
)
134+
self.param_name = param_name
135+
self.param_constraint = param_constraint
136+
137+
138+
class PreProcessPayloadIngestionException(PayloadIngestionException):
139+
"""
140+
Raised when an error occurs during the pre-processing phase of payload ingestion.
141+
This is specifically when plugin hook pre_ingest_process raises an exception.
142+
"""
143+
144+
def __init__(
145+
self,
146+
payload_id: str,
147+
destination_table: str,
148+
target: str,
149+
message: str,
150+
resolvable_by: ResolvableBy = None,
151+
):
152+
super().__init__(
153+
message=message,
154+
destination_table=destination_table,
155+
target=target,
156+
payload_id=payload_id,
157+
resolvable_by=resolvable_by,
158+
)
159+
160+
161+
class PostProcessPayloadIngestionException(PayloadIngestionException):
162+
"""
163+
Raised when an error occurs during the post-processing phase of payload ingestion.
164+
This is specifically when plugin hook post_ingest_process raises an exception.
165+
"""
166+
167+
def __init__(
168+
self,
169+
payload_id: str,
170+
destination_table: str,
171+
target: str,
172+
message: str,
173+
resolvable_by: ResolvableBy = None,
174+
):
175+
super().__init__(
176+
message=message,
177+
destination_table=destination_table,
178+
target=target,
179+
payload_id=payload_id,
180+
resolvable_by=resolvable_by,
181+
)

0 commit comments

Comments
 (0)