Coverage for /usr/local/lib/python3.12/site-packages/prefect/exceptions.py: 57%
130 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 11:21 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 11:21 +0000
1"""
2Prefect-specific exceptions.
3"""
5import inspect 1a
6import traceback 1a
7from collections.abc import Iterable 1a
8from types import ModuleType, TracebackType 1a
9from typing import TYPE_CHECKING, Any, Callable, Optional 1a
11from httpx import HTTPStatusError 1a
12from pydantic import ValidationError 1a
13from typing_extensions import Self 1a
15if TYPE_CHECKING: 15 ↛ 16line 15 didn't jump to line 16 because the condition on line 15 was never true1a
16 from prefect.states import State
19def _trim_traceback( 1a
20 tb: TracebackType | None, remove_modules: Iterable[ModuleType]
21) -> TracebackType | None:
22 """
23 Utility to remove frames from specific modules from a traceback.
25 Only frames from the front of the traceback are removed. Once a traceback frame
26 is reached that does not originate from `remove_modules`, it is returned.
28 Args:
29 tb: The traceback to trim.
30 remove_modules: An iterable of module objects to remove.
32 Returns:
33 A traceback, or `None` if all traceback frames originate from an excluded module
35 """
36 strip_paths = [
37 module.__file__ for module in remove_modules if module.__file__ is not None
38 ]
39 while tb and any(
40 module_path in str(tb.tb_frame.f_globals.get("__file__", ""))
41 for module_path in strip_paths
42 ):
43 tb = tb.tb_next
45 return tb
48def exception_traceback(exc: Exception) -> str: 1a
49 """
50 Convert an exception to a printable string with a traceback
51 """
52 tb = traceback.TracebackException.from_exception(exc)
53 return "".join(list(tb.format()))
56class PrefectException(Exception): 1a
57 """
58 Base exception type for Prefect errors.
59 """
62class CrashedRun(PrefectException): 1a
63 """
64 Raised when the result from a crashed run is retrieved.
66 This occurs when a string is attached to the state instead of an exception or if
67 the state's data is null.
68 """
71class FailedRun(PrefectException): 1a
72 """
73 Raised when the result from a failed run is retrieved and an exception is not
74 attached.
76 This occurs when a string is attached to the state instead of an exception or if
77 the state's data is null.
78 """
81class CancelledRun(PrefectException): 1a
82 """
83 Raised when the result from a cancelled run is retrieved and an exception
84 is not attached.
86 This occurs when a string is attached to the state instead of an exception
87 or if the state's data is null.
88 """
91class PausedRun(PrefectException): 1a
92 """
93 Raised when the result from a paused run is retrieved.
94 """
96 def __init__( 1a
97 self, *args: Any, state: Optional["State[Any]"] = None, **kwargs: Any
98 ) -> None:
99 super().__init__(*args, **kwargs)
100 self.state = state
103class UnfinishedRun(PrefectException): 1a
104 """
105 Raised when the result from a run that is not finished is retrieved.
107 For example, if a run is in a SCHEDULED, PENDING, CANCELLING, or RUNNING state.
108 """
111class MissingFlowError(PrefectException): 1a
112 """
113 Raised when a given flow name is not found in the expected script.
114 """
117class UnspecifiedFlowError(PrefectException): 1a
118 """
119 Raised when multiple flows are found in the expected script and no name is given.
120 """
123class MissingResult(PrefectException): 1a
124 """
125 Raised when a result is missing from a state; often when result persistence is
126 disabled and the state is retrieved from the API.
127 """
130class ScriptError(PrefectException): 1a
131 """
132 Raised when a script errors during evaluation while attempting to load data
133 """
135 def __init__( 1a
136 self,
137 user_exc: Exception,
138 path: str,
139 ) -> None:
140 import prefect.utilities.importtools
142 message = f"Script at {str(path)!r} encountered an exception: {user_exc!r}"
143 super().__init__(message)
144 self.user_exc = user_exc
146 # Strip script run information from the traceback
147 self.user_exc.__traceback__ = _trim_traceback(
148 self.user_exc.__traceback__,
149 remove_modules=[prefect.utilities.importtools],
150 )
153class ParameterTypeError(PrefectException): 1a
154 """
155 Raised when a parameter does not pass Pydantic type validation.
156 """
158 def __init__(self, msg: str): 1a
159 super().__init__(msg)
161 @classmethod 1a
162 def from_validation_error(cls, exc: ValidationError) -> Self: 1a
163 bad_params = [
164 f"{'.'.join(str(item) for item in err['loc'])}: {err['msg']}"
165 for err in exc.errors()
166 ]
167 msg = "Flow run received invalid parameters:\n - " + "\n - ".join(bad_params)
168 return cls(msg)
171class ParameterBindError(TypeError, PrefectException): 1a
172 """
173 Raised when args and kwargs cannot be converted to parameters.
174 """
176 def __init__(self, msg: str): 1a
177 super().__init__(msg)
179 @classmethod 1a
180 def from_bind_failure( 1a
181 cls,
182 fn: Callable[..., Any],
183 exc: TypeError,
184 call_args: tuple[Any, ...],
185 call_kwargs: dict[str, Any],
186 ) -> Self:
187 fn_signature = str(inspect.signature(fn)).strip("()")
189 base = f"Error binding parameters for function '{fn.__name__}': {exc}"
190 signature = f"Function '{fn.__name__}' has signature '{fn_signature}'"
191 received = f"received args: {call_args} and kwargs: {list(call_kwargs.keys())}"
192 msg = f"{base}.\n{signature} but {received}."
193 return cls(msg)
196class SignatureMismatchError(PrefectException, TypeError): 1a
197 """Raised when parameters passed to a function do not match its signature."""
199 def __init__(self, msg: str): 1a
200 super().__init__(msg)
202 @classmethod 1a
203 def from_bad_params( 1a
204 cls, expected_params: list[str], provided_params: list[str]
205 ) -> Self:
206 msg = (
207 f"Function expects parameters {expected_params} but was provided with"
208 f" parameters {provided_params}"
209 )
210 return cls(msg)
213class ObjectNotFound(PrefectException): 1a
214 """
215 Raised when the client receives a 404 (not found) from the API.
216 """
218 def __init__( 1a
219 self,
220 http_exc: Exception,
221 help_message: Optional[str] = None,
222 *args: Any,
223 **kwargs: Any,
224 ) -> None:
225 self.http_exc = http_exc
226 self.help_message = help_message
227 super().__init__(help_message, *args, **kwargs)
229 def __str__(self) -> str: 1a
230 return self.help_message or super().__str__()
233class ObjectAlreadyExists(PrefectException): 1a
234 """
235 Raised when the client receives a 409 (conflict) from the API.
236 """
238 def __init__(self, http_exc: Exception, *args: Any, **kwargs: Any) -> None: 1a
239 self.http_exc = http_exc
240 super().__init__(*args, **kwargs)
243class ObjectLimitReached(PrefectException): 1a
244 """
245 Raised when the client receives a 403 (forbidden) from the API due to reaching an object limit (e.g. maximum number of deployments).
246 """
248 def __init__(self, http_exc: Exception, *args: Any, **kwargs: Any) -> None: 1a
249 self.http_exc = http_exc
250 super().__init__(*args, **kwargs)
253class ObjectUnsupported(PrefectException): 1a
254 """
255 Raised when the client receives a 403 (forbidden) from the API due to an unsupported object (i.e. requires a specific Prefect Cloud tier).
256 """
258 def __init__(self, http_exc: Exception, *args: Any, **kwargs: Any) -> None: 1a
259 self.http_exc = http_exc
260 super().__init__(*args, **kwargs)
263class UpstreamTaskError(PrefectException): 1a
264 """
265 Raised when a task relies on the result of another task but that task is not
266 'COMPLETE'
267 """
270class MissingContextError(PrefectException, RuntimeError): 1a
271 """
272 Raised when a method is called that requires a task or flow run context to be
273 active but one cannot be found.
274 """
277class MissingProfileError(PrefectException, ValueError): 1a
278 """
279 Raised when a profile name does not exist.
280 """
283class ReservedArgumentError(PrefectException, TypeError): 1a
284 """
285 Raised when a function used with Prefect has an argument with a name that is
286 reserved for a Prefect feature
287 """
290class InvalidNameError(PrefectException, ValueError): 1a
291 """
292 Raised when a name contains characters that are not permitted.
293 """
296class PrefectSignal(BaseException): 1a
297 """
298 Base type for signal-like exceptions that should never be caught by users.
299 """
302class Abort(PrefectSignal): 1a
303 """
304 Raised when the API sends an 'ABORT' instruction during state proposal.
306 Indicates that the run should exit immediately.
307 """
310class Pause(PrefectSignal): 1a
311 """
312 Raised when a flow run is PAUSED and needs to exit for resubmission.
313 """
315 def __init__( 1a
316 self, *args: Any, state: Optional["State[Any]"] = None, **kwargs: Any
317 ) -> None:
318 super().__init__(*args, **kwargs)
319 self.state = state
322class ExternalSignal(BaseException): 1a
323 """
324 Base type for external signal-like exceptions that should never be caught by users.
325 """
328class TerminationSignal(ExternalSignal): 1a
329 """
330 Raised when a flow run receives a termination signal.
331 """
333 def __init__(self, signal: int): 1a
334 self.signal = signal
337class PrefectHTTPStatusError(HTTPStatusError): 1a
338 """
339 Raised when client receives a `Response` that contains an HTTPStatusError.
341 Used to include API error details in the error messages that the client provides users.
342 """
344 @classmethod 1a
345 def from_httpx_error(cls: type[Self], httpx_error: HTTPStatusError) -> Self: 1a
346 """
347 Generate a `PrefectHTTPStatusError` from an `httpx.HTTPStatusError`.
348 """
349 try:
350 details = httpx_error.response.json()
351 except Exception:
352 details = None
354 error_message, *more_info = str(httpx_error).split("\n")
356 if details:
357 message_components = [error_message, f"Response: {details}", *more_info]
358 else:
359 message_components = [error_message, *more_info]
361 new_message = "\n".join(message_components)
363 return cls(
364 new_message, request=httpx_error.request, response=httpx_error.response
365 )
368class MappingLengthMismatch(PrefectException): 1a
369 """
370 Raised when attempting to call Task.map with arguments of different lengths.
371 """
374class MappingMissingIterable(PrefectException): 1a
375 """
376 Raised when attempting to call Task.map with all static arguments
377 """
380class BlockMissingCapabilities(PrefectException): 1a
381 """
382 Raised when a block does not have required capabilities for a given operation.
383 """
386class ProtectedBlockError(PrefectException): 1a
387 """
388 Raised when an operation is prevented due to block protection.
389 """
392class InvalidRepositoryURLError(PrefectException): 1a
393 """Raised when an incorrect URL is provided to a GitHub filesystem block."""
396class InfrastructureError(PrefectException): 1a
397 """
398 A base class for exceptions related to infrastructure blocks
399 """
402class InfrastructureNotFound(PrefectException): 1a
403 """
404 Raised when infrastructure is missing, likely because it has exited or been
405 deleted.
406 """
409class InfrastructureNotAvailable(PrefectException): 1a
410 """
411 Raised when infrastructure is not accessible from the current machine. For example,
412 if a process was spawned on another machine it cannot be managed.
413 """
416class NotPausedError(PrefectException): 1a
417 """Raised when attempting to unpause a run that isn't paused."""
420class FlowPauseTimeout(PrefectException): 1a
421 """Raised when a flow pause times out"""
424class FlowRunWaitTimeout(PrefectException): 1a
425 """Raised when a flow run takes longer than a given timeout"""
428class PrefectImportError(ImportError): 1a
429 """
430 An error raised when a Prefect object cannot be imported due to a move or removal.
431 """
433 def __init__(self, message: str) -> None: 1a
434 super().__init__(message)
437class SerializationError(PrefectException): 1a
438 """
439 Raised when an object cannot be serialized.
440 """
443class ConfigurationError(PrefectException): 1a
444 """
445 Raised when a configuration is invalid.
446 """
449class ProfileSettingsValidationError(PrefectException): 1a
450 """
451 Raised when a profile settings are invalid.
452 """
454 def __init__(self, errors: list[tuple[Any, ValidationError]]) -> None: 1a
455 self.errors = errors
458class HashError(PrefectException): 1a
459 """Raised when hashing objects fails"""