Coverage for dataexcept/dataengineering_exceptions.py: 100%
47 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-03 20:46 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-03 20:46 +0000
1"""Custom exceptions for data engineering workflows."""
3from __future__ import annotations
5from typing import Optional
7from .base import DataExceptError
8from .redaction import redact_if_url
11class DataEngineeringError(DataExceptError):
12 """Base exception for data engineering errors."""
14 pass
17class ETLJobError(DataEngineeringError):
18 """Raised when an ETL job fails to complete successfully."""
20 def __init__(self, job_name: str, message: Optional[str] = None) -> None:
21 """Initialize ETLJobError.
23 Args:
24 job_name: Name of the ETL job.
25 message: Optional custom error message.
26 """
27 self.job_name = job_name
28 default = f"ETL job '{job_name}' failed"
29 super().__init__(message or default)
32class SchemaEvolutionError(DataEngineeringError):
33 """Raised when database schema evolution fails."""
35 def __init__(self, schema_version: str, reason: Optional[str] = None) -> None:
36 """Initialize SchemaEvolutionError.
38 Args:
39 schema_version: Version of the schema being applied.
40 reason: Optional explanation of the failure.
41 """
42 self.schema_version = schema_version
43 self.reason = reason
44 msg = f"Schema evolution to {schema_version} failed"
45 if reason:
46 msg += f": {reason}"
47 super().__init__(msg)
50class DataTransformationError(DataEngineeringError):
51 """Raised when a data transformation step fails."""
53 def __init__(self, step: str, details: Optional[str] = None) -> None:
54 """Initialize DataTransformationError.
56 Args:
57 step: Name of the transformation step.
58 details: Optional details about the failure.
59 """
60 self.step = step
61 self.details = details
62 msg = f"Data transformation '{step}' failed"
63 if details:
64 msg += f": {details}"
65 super().__init__(msg)
68class BatchProcessingError(DataEngineeringError):
69 """Raised when processing a data batch fails."""
71 def __init__(self, batch_id: str, original: Optional[Exception] = None) -> None:
72 """Initialize BatchProcessingError.
74 Args:
75 batch_id: Identifier of the batch being processed.
76 original: Optional underlying exception.
77 """
78 self.batch_id = batch_id
79 self.original = original
80 msg = f"Batch '{batch_id}' processing failed"
81 if original:
82 msg += f": {original}"
83 super().__init__(msg)
86class DataWarehouseConnectionError(DataEngineeringError):
87 """Raised when a connection to a data warehouse cannot be established."""
89 def __init__(self, warehouse: str, message: Optional[str] = None) -> None:
90 """Initialize DataWarehouseConnectionError.
92 Args:
93 warehouse: Identifier of the data warehouse.
94 message: Optional custom error message.
95 """
96 self.warehouse = warehouse
97 default = f"Failed to connect to warehouse '{warehouse}'"
98 super().__init__(message or default)
101class MissingPartitionError(DataEngineeringError):
102 """Raised when a required data partition is missing."""
104 def __init__(
105 self, partition: str, location: str, message: Optional[str] = None
106 ) -> None:
107 """Initialize MissingPartitionError.
109 Args:
110 partition: Name of the missing partition.
111 location: Data location checked for the partition.
112 message: Optional custom error message.
113 """
114 self.partition = partition
115 self.location = redact_if_url(location)
116 default = f"Partition '{partition}' not found at {location}"
117 super().__init__(message or default)
120__all__ = [
121 "DataEngineeringError",
122 "ETLJobError",
123 "SchemaEvolutionError",
124 "DataTransformationError",
125 "BatchProcessingError",
126 "DataWarehouseConnectionError",
127 "MissingPartitionError",
128]