Changeset View
Changeset View
Standalone View
Standalone View
looper/exceptions.py
| """Publicly usable exceptions. | """Publicly usable exceptions. | ||||
| Some of those exceptions may have more specific subclasses (such | Some of those exceptions may have more specific subclasses (such | ||||
| as BraintreeError), but those shouldn't be used outside the looper | as BraintreeError), but those shouldn't be used outside the looper | ||||
| Django app. | Django app. | ||||
| """ | """ | ||||
| import typing | from typing import Iterable, List, Optional, Set | ||||
| class LooperError(Exception): | class LooperError(Exception): | ||||
| """Superclass of all Looper-specific exceptions.""" | """Superclass of all Looper-specific exceptions.""" | ||||
| def __init__(self, message: str) -> None: | def __init__(self, message: str) -> None: | ||||
| super().__init__(message) | super().__init__(message) | ||||
| # The superclass stores the message in self.args[0], which isn't as nice. | # The superclass stores the message in self.args[0], which isn't as nice. | ||||
| self.message = message | self.message = message | ||||
| class RecaptchaConfigurationError(LooperError): | |||||
| """Raised when ReCaptcha is misconfigured.""" | |||||
| class GatewayConfigurationError(LooperError): | |||||
| """Raised when an Gateway provider is misconfigured.""" | |||||
| class GatewayConfigurationMissing(LooperError): | class GatewayConfigurationMissing(LooperError): | ||||
| """Raised when an Gateway provider is used but not configured.""" | """Raised when an Gateway provider is used but not configured.""" | ||||
| class GatewayNotImplemented(LooperError): | class GatewayNotImplemented(LooperError): | ||||
| """Raised when a provider is requested that does not exist.""" | """Raised when a provider is requested that does not exist.""" | ||||
| class GatewayError(LooperError): | class GatewayError(LooperError): | ||||
| """Generic gateway exception. Supports an additional list of errors.""" | """Generic gateway exception. Supports an additional list of errors.""" | ||||
| def __init__(self, message: str, errors: typing.Optional[typing.Iterable[str]] = None) -> None: | def __init__(self, message: str, errors: Optional[Iterable[str]] = None) -> None: | ||||
| super().__init__(message) | super().__init__(message) | ||||
| self.errors: typing.List[str] = list(errors) if errors else [] | self.errors: List[str] = list(errors) if errors else [] | ||||
| assert all(isinstance(err, str) for err in self.errors) | assert all(isinstance(err, str) for err in self.errors) | ||||
| def with_errors(self) -> str: | def with_errors(self) -> str: | ||||
| if self.errors: | if self.errors: | ||||
| return f'{self.message}: {"; ".join(self.errors)}' | return f'{self.message}: {"; ".join(self.errors)}' | ||||
| return self.message | return self.message | ||||
| def __str__(self) -> str: | def __str__(self) -> str: | ||||
| Show All 13 Lines | |||||
| class IncorrectStatusError(LooperError): | class IncorrectStatusError(LooperError): | ||||
| """The requested action is not allowed in the current state. | """The requested action is not allowed in the current state. | ||||
| Raised by functions on database models requiring the model's 'status' | Raised by functions on database models requiring the model's 'status' | ||||
| property to have a certain value, when this requirement isn't met. | property to have a certain value, when this requirement isn't met. | ||||
| """ | """ | ||||
| def __init__(self, message: str, actual_status: str, required_status: typing.Set[str]) -> None: | def __init__(self, message: str, actual_status: str, required_status: Set[str]) -> None: | ||||
| super().__init__(message) | super().__init__(message) | ||||
| self.actual_status = actual_status | self.actual_status = actual_status | ||||
| self.required_status = required_status | self.required_status = required_status | ||||