Skip to content

harborapi.exceptions

EXCEPTIONS_MAP = {400: BadRequest, 401: Unauthorized, 403: Forbidden, 404: NotFound, 405: MethodNotAllowed, 409: Conflict, 412: PreconditionFailed, 415: UnsupportedMediaType, 422: UnprocessableEntity, 500: InternalServerError} module-attribute

HarborAPIException

Bases: Exception

StatusError(*args, errors=None, **kwargs)

Bases: HarborAPIException

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

__cause__: Optional[HTTPStatusError] = None instance-attribute

The underlying HTTPX exception that caused this exception. Automatically assigned when raised from a HTTPX exception.

errors: List[Error] = [] instance-attribute

A list of errors returned by the Harbor API.

response: Optional[Response] property

status_code: int property

The status code of the underlying HTTPX exception.

Returns:

Type Description
Optional[int]

The status code of the underlying HTTPX exception. Returns 0 if no response is available.

__str__()

Return a string representation of this exception.

Source code in harborapi/exceptions.py
def __str__(self) -> str:
    """Return a string representation of this exception."""
    # HTTPX exceptions are not very informative, and it is hard to debug
    # failing tests without knowing the response text. So, we append the
    # response text to the exception message.

    # An HTTPX exception will have a single arg that looks like this:
    # "Server error '500 INTERNAL SERVER ERROR' for url 'http://localhost:61656/api/v2.0/foo'\nFor more information check: https://httpstatuses.com/500"
    # We only want the first part, so we partition on the newline
    original_message = super().__str__().partition("\n")[0]
    response_text = self.response.text if self.response else ""
    return f"{original_message}: {response_text}"

BadRequest(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

Unauthorized(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

Forbidden(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

NotFound(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

MethodNotAllowed(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

Conflict(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

PreconditionFailed(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

UnsupportedMediaType(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

UnprocessableEntity(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

InternalServerError(*args, errors=None, **kwargs)

Bases: StatusError

Initialize a StatusError.

Parameters:

Name Type Description Default
*args Any

Positional arguments to pass to the base Exception class.

()
errors Optional[Errors]

A list of errors returned by the Harbor API.

None
**kwargs Any

Keyword arguments to pass to the base Exception class.

{}
Source code in harborapi/exceptions.py
def __init__(
    self,
    *args: Any,
    errors: Optional[Errors] = None,
    **kwargs: Any,
):
    """Initialize a StatusError.

    Parameters
    ----------
    *args : Any
        Positional arguments to pass to the base Exception class.
    errors : Optional[Errors]
        A list of errors returned by the Harbor API.
    **kwargs : Any
        Keyword arguments to pass to the base Exception class.
    """
    super().__init__(*args, **kwargs)

    self.__cause__: Optional[HTTPStatusError] = None
    """The underlying HTTPX exception that caused this exception.
    Automatically assigned when raised from a HTTPX exception."""

    self.errors: List[Error] = []
    """A list of errors returned by the Harbor API."""
    if isinstance(errors, Errors) and errors.errors:
        self.errors = errors.errors

check_response_status(response, missing_ok=None)

Raises an exception if the response status is not 2xx.

Exceptions are wrapped in a StatusError if the response contains errors.

Parameters:

Name Type Description Default
response Response

The response to check.

required
missing_ok Optional[bool]

DEPRECATED: If True, do not raise an exception if the status is 404.

None
Source code in harborapi/exceptions.py
def check_response_status(
    response: Response, missing_ok: Optional[bool] = None
) -> None:
    """Raises an exception if the response status is not 2xx.

    Exceptions are wrapped in a `StatusError` if the response contains errors.

    Parameters
    ----------
    response : Response
        The response to check.
    missing_ok : Optional[bool]
        DEPRECATED: If `True`, do not raise an exception if the status is 404.
    """
    if missing_ok is not None:
        warnings.warn(
            "The 'missing_ok' parameter is deprecated and will be removed in version 1.0.0",
            DeprecationWarning,
        )

    try:
        response.raise_for_status()
    except HTTPStatusError as e:
        status_code = response.status_code
        # TODO: remove in v1.0.0
        if missing_ok and status_code == 404:
            logger.warning("%s not found", response.request.url)
            return
        errors = try_parse_errors(response)
        logger.error(
            "Harbor API returned status code %s for %s",
            response.status_code,
            response.url,
        )
        exc = EXCEPTIONS_MAP.get(status_code, StatusError)
        raise exc(*e.args, errors=errors) from e

try_parse_errors(response)

Attempts to return the errors from a response.

See: models.Errors

Parameters:

Name Type Description Default
response Response
required

Returns:

Type Description
Optional[Errors]

The errors from the response.

Source code in harborapi/exceptions.py
def try_parse_errors(response: Response) -> Optional[Errors]:
    """Attempts to return the errors from a response.

    See: `models.Errors`

    Parameters
    ----------
    response : Response

    Returns
    -------
    Optional[Errors]
        The errors from the response.
    """
    from .utils import is_json  # avoid circular import

    if is_json(response):
        try:
            return Errors(**response.json())
        except Exception as e:
            logger.error(
                "Failed to parse error response from %s as JSON: %s", response.url, e
            )
    return None