Source code for selinon.errors
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ######################################################################
# Copyright (C) 2016-2018 Fridolin Pokorny, fridolin.pokorny@gmail.com
# This file is part of Selinon project.
# ######################################################################
"""Errors and exceptions that can occur in Selinon code base."""
import json
[docs]class SelinonException(Exception):
"""Base Selinon exception in exception hierarchy."""
[docs]class UnsupportedCeleryError(Exception):
"""An exception raised when using unsupported Celery version."""
[docs]class FatalTaskError(SelinonException):
"""An exception that is raised by task on fatal error - task will be not retried."""
[docs]class UnknownFlowError(SelinonException):
"""Raised if there was requested or referenced flow that is not stated in the YAML configuration file."""
[docs]class UnknownStorageError(SelinonException):
"""Raised if there was requested or referenced storage that is not stated in the YAML configuration file."""
[docs]class ConfigurationError(SelinonException):
"""Raised on errors that indicate errors in the configuration files."""
[docs]class SelectiveNoPathError(SelinonException):
"""Raised when there is no path in the flow to requested node in selective task runs."""
[docs]class NoParentNodeError(SelinonException):
"""An exception raised when requested parent node (task/flow), but no such parent defined."""
[docs]class RequestError(SelinonException):
"""An error raised if there was an issue with request issued by user - usually means bad usage error."""
[docs]class UnknownError(SelinonException):
"""An error raised on unknown scenarios - possibly some bug in code."""
[docs]class Retry(SelinonException):
"""Retry task as would Celery do except you can only specify countdown for retry."""
def __init__(self, countdown):
"""Init retry.
:param countdown: countdown in seconds
"""
self.countdown = countdown
super().__init__(self, countdown)
[docs]class FlowError(SelinonException):
"""An exception that is raised once there is an error in the flow on runtime - some nodes failed."""
def __init__(self, state):
"""Make sure flow errors capture final state of the flow.
:param state: final flow state
"""
super().__init__(json.dumps(state))
@property
def state(self):
"""Get structured flow state."""
return json.loads(str(self))
[docs]class DispatcherRetry(SelinonException):
"""Force retry the whole flow - if flow arguments are provided, flow will continue where it was left."""
def __init__(self, keep_state=True, adjust_retry_count=True):
"""Retry dispatcher causing flow state to be reinspected.
:param keep_state: the current state should be kept otherwise the whole flow will start from the beginning
:type keep_state: bool
:param adjust_retry_count: adjust flow retry count if needed, will cause flow failure once retry count reaches 0
:type adjust_retry_count: bool
"""
super().__init__()
self.keep_state = keep_state
self.adjust_retry_count = adjust_retry_count
[docs]class StorageError(SelinonException):
"""Raised to notify about storage errors (e.g. storage goes down)."""
[docs]class MigrationNotNeeded(SelinonException):
"""Raised when a migration is requested, but config changes do not require it."""
[docs]class MigrationSkew(SelinonException):
"""Raised if worker hasn't needed migration files."""
def __init__(self, *args, available_migration_version):
"""Instantiate and track info about migration skew.
:param available_migration_version:
"""
self.available_migration_version = available_migration_version
super().__init__(*args)
[docs]class MigrationException(SelinonException):
"""Base exception for migration related exceptions."""
TAINTED_FLOW_STRATEGY = 'UNKNOWN'
def __init__(self, *args, migration_version, latest_migration_version, tainting_nodes=None, tainted_edge=None):
"""Instantiate base exception for migrations.
:param args: additional arguments for base exception
:param migration_version: the current migration version
:param latest_migration_version: the latest migration version based on migration directory content
:param tainting_nodes: nodes that run tainted flow
:param tainted_edge: edges that tainted flow
"""
self.migration_version = migration_version
self.latest_migration_version = latest_migration_version
self.tainting_nodes = tainting_nodes
self.tainted_edge = tainted_edge
super().__init__(*args)
[docs]class MigrationFlowFail(MigrationException):
"""An exception raised when a flow should fail - i.e. migration causing tainting of flow should fail flow."""
TAINTED_FLOW_STRATEGY = 'FAIL'
[docs]class MigrationFlowRetry(MigrationException):
"""An exception raised when a flow should be retried - i.e. migration causing tainting of flow should retry flow."""
TAINTED_FLOW_STRATEGY = 'RETRY'
[docs]class CacheMissError(SelinonException):
"""An error raised when there is requested an item from cache that is not stored in cache."""
[docs]class ConfigNotInitializedError(SelinonException):
"""An error raised when the configuration was requested, but not initialized."""