1# coding: utf-8
2# Copyright (c) 2016, 2021, Oracle and/or its affiliates.  All rights reserved.
3# This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
4
5from oci._vendor.requests.exceptions import RequestException as BaseRequestException
6from oci._vendor.requests.exceptions import ConnectTimeout as BaseConnectTimeout
7
8
9class ServiceError(Exception):
10    """The service returned an error response."""
11
12    def __init__(self, status, code, headers, message, **kwargs):
13        self.status = status
14        self.code = code
15        self.headers = headers
16        self.message = message
17        self.original_request = kwargs.get('original_request')
18        self.request_id = self._get_opc_request_id()
19
20        if not message:
21            message = "The service returned error code %s" % self.status
22
23        super(ServiceError, self).__init__({
24            "opc-request-id": self.request_id,
25            "code": code,
26            "message": message,
27            "status": status
28        })
29
30    def _get_opc_request_id(self):
31        if self.headers.get("opc-request-id"):
32            return self.headers.get("opc-request-id")
33        elif self.original_request and self.original_request.header_params:
34            return self.original_request.header_params.get("opc-request-id")
35        else:
36            return None
37
38
39class TransientServiceError(ServiceError):
40    """A transient service error occurred"""
41
42
43class ClientError(Exception):
44    """A client-side error occurred.."""
45
46
47class ConfigFileNotFound(ClientError):
48    """Config file not be found."""
49
50
51class InvalidConfig(ClientError):
52    """The config object is missing required keys or contains malformed values.
53
54    For example:
55
56    .. code-block:: python
57
58        raise InvalidConfig({
59            "region": "missing",
60            "key_id": "malformed'
61        })
62    """
63    def __init__(self, errors):
64        """:param errors: {config key: error code}"""
65        self.errors = errors
66
67    def __str__(self):
68        return str(self.errors)
69
70
71class InvalidPrivateKey(ClientError):
72    """The provided key is not a private key, or the provided passphrase is incorrect."""
73
74
75class MissingPrivateKeyPassphrase(InvalidPrivateKey):
76    """The provided key requires a passphrase."""
77
78
79class InvalidKeyFilePath(ClientError):
80    """The value is expected to be a file name but it's not a valid key_file path."""
81
82
83class ProfileNotFound(ClientError):
84    """The specified profile was not found in the config file."""
85
86
87class WaitUntilNotSupported(ClientError):
88    """wait_until is not supported by this response."""
89
90
91class MaximumWaitTimeExceeded(ClientError):
92    """Maximum wait time has been exceeded."""
93
94
95class MultipartUploadError(Exception):
96    """
97    Exception thrown when an error with a multipart upload occurs. As multipart uploads can be
98    parallelised, this error contains a collection of errors which caused individual part uploads
99    to fail
100    """
101    def __init__(self, **kwargs):
102        """
103        :param queue error_causes_queue:
104            A queue containing errors which occured during the multipart upload
105        """
106        self.error_causes = []
107        if 'error_causes_queue' in kwargs:
108            while not kwargs['error_causes_queue'].empty():
109                self.error_causes.append(kwargs['error_causes_queue'].get())
110
111
112class CompositeOperationError(Exception):
113    """
114    An exception occurred during a composite operation (e.g. launching an instance and waiting for state)
115    but part of the composite operation succeeded. This exception has the following attributes:
116
117    :var list partial_results: Any partial results which are available (e.g. if the :py:meth:`~oci.core.ComputeClient.launch_instance` succeeded and the waiting for state failed then this will contain the :py:meth:`~oci.core.ComputeClient.launch_instance` result)
118    :var Exception cause: The exception which caused the composite operation to fail
119    """
120
121    def __init__(self, partial_results=[], cause=None):
122        self.partial_results = partial_results
123        self.cause = cause
124
125
126class RequestException(BaseRequestException):
127    """An exception occurred when making the request"""
128
129
130class ConnectTimeout(BaseConnectTimeout):
131    """The request timed out while trying to connect to the remote server.
132
133    Requests that produced this error are safe to retry.
134    """
135
136
137class MissingEndpointForNonRegionalServiceClientError(ValueError):
138    """No endpoint value was provided when trying to create a non-regional service client.
139    """
140