Skip to content

Exceptions

The exception hierarchy maps HTTP status codes to typed exceptions. All HTTP exceptions inherit from ForecastHTTPError and carry status_code, response_body, and url attributes.

exceptions

Exception hierarchy for the Harvest Forecast API client.

HTTP_BAD_REQUEST module-attribute

HTTP_BAD_REQUEST = 400

HTTP_UNAUTHORIZED module-attribute

HTTP_UNAUTHORIZED = 401

HTTP_FORBIDDEN module-attribute

HTTP_FORBIDDEN = 403

HTTP_NOT_FOUND module-attribute

HTTP_NOT_FOUND = 404

HTTP_TOO_MANY module-attribute

HTTP_TOO_MANY = 429

HTTP_UNPROCESSABLE module-attribute

HTTP_UNPROCESSABLE = 422

HTTP_SERVER_MIN module-attribute

HTTP_SERVER_MIN = 500

HTTP_SERVER_MAX module-attribute

HTTP_SERVER_MAX = 600

__all__ module-attribute

__all__ = [
    "ForecastAuthError",
    "ForecastError",
    "ForecastHTTPError",
    "ForecastNotFoundError",
    "ForecastRateLimitError",
    "ForecastServerError",
    "ForecastValidationError",
]

ForecastError

Bases: Exception

Base for all exceptions raised by harvest_forecast.

ForecastHTTPError

ForecastHTTPError(
    status_code: int, response_body: str, url: str
)

Bases: ForecastError

HTTP error from the Forecast API.

Carries status_code, response_body, and url. Subclasses map specific status-code ranges; this class serves as the catch-all for unrecognised codes and as the base for all HTTP exceptions.

Source code in src/harvest_forecast/exceptions.py
def __init__(self, status_code: int, response_body: str, url: str) -> None:
    self.status_code = status_code
    self.response_body = response_body
    self.url = url
    super().__init__(self._format_message())

status_code instance-attribute

status_code: int = status_code

response_body instance-attribute

response_body: str = response_body

url instance-attribute

url: str = url

from_response classmethod

from_response(response: Response) -> ForecastHTTPError
Source code in src/harvest_forecast/exceptions.py
@classmethod
def from_response(cls, response: httpx.Response) -> ForecastHTTPError:
    status = response.status_code
    body = response.text
    url = str(response.url)

    if status in (HTTP_UNAUTHORIZED, HTTP_FORBIDDEN):
        return ForecastAuthError(status, body, url)
    if status == HTTP_NOT_FOUND:
        return ForecastNotFoundError(status, body, url)
    if status == HTTP_TOO_MANY:
        return ForecastRateLimitError(
            status, body, url, retry_after=_parse_retry_after(response)
        )
    if HTTP_SERVER_MIN <= status < HTTP_SERVER_MAX:
        return ForecastServerError(status, body, url)
    if status in (HTTP_BAD_REQUEST, HTTP_UNPROCESSABLE):
        return ForecastValidationError(status, body, url)
    return ForecastHTTPError(status, body, url)

ForecastAuthError

ForecastAuthError(
    status_code: int, response_body: str, url: str
)

Bases: ForecastHTTPError

401 or 403 — authentication or authorization failure.

Source code in src/harvest_forecast/exceptions.py
def __init__(self, status_code: int, response_body: str, url: str) -> None:
    self.status_code = status_code
    self.response_body = response_body
    self.url = url
    super().__init__(self._format_message())

ForecastNotFoundError

ForecastNotFoundError(
    status_code: int, response_body: str, url: str
)

Bases: ForecastHTTPError

404 — resource not found.

Source code in src/harvest_forecast/exceptions.py
def __init__(self, status_code: int, response_body: str, url: str) -> None:
    self.status_code = status_code
    self.response_body = response_body
    self.url = url
    super().__init__(self._format_message())

ForecastRateLimitError

ForecastRateLimitError(
    status_code: int,
    response_body: str,
    url: str,
    *,
    retry_after: float | None = None,
)

Bases: ForecastHTTPError

429 — rate limited. Carries retry_after from the Retry-After header.

Source code in src/harvest_forecast/exceptions.py
def __init__(
    self,
    status_code: int,
    response_body: str,
    url: str,
    *,
    retry_after: float | None = None,
) -> None:
    self.retry_after = retry_after
    super().__init__(status_code, response_body, url)

retry_after instance-attribute

retry_after: float | None = retry_after

ForecastServerError

ForecastServerError(
    status_code: int, response_body: str, url: str
)

Bases: ForecastHTTPError

5xx — server-side error.

Source code in src/harvest_forecast/exceptions.py
def __init__(self, status_code: int, response_body: str, url: str) -> None:
    self.status_code = status_code
    self.response_body = response_body
    self.url = url
    super().__init__(self._format_message())

ForecastValidationError

ForecastValidationError(
    status_code: int, response_body: str, url: str
)

Bases: ForecastHTTPError

400 or 422 — API returned a validation error body.

Source code in src/harvest_forecast/exceptions.py
def __init__(self, status_code: int, response_body: str, url: str) -> None:
    self.status_code = status_code
    self.response_body = response_body
    self.url = url
    super().__init__(self._format_message())