Completed
Push — master ( d181e1...025c95 )
by ARCANEDEV
08:05
created

ErrorsHandler::getExceptionByCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
ccs 2
cts 2
cp 1
crap 1
1
<?php namespace Arcanedev\Stripe\Utilities;
2
3
use Arcanedev\Stripe\Contracts\Utilities\ApiErrorsHandlerInterface;
4
use Arcanedev\Stripe\Exceptions\ApiException;
5
use Arcanedev\Stripe\Exceptions\AuthenticationException;
6
use Arcanedev\Stripe\Exceptions\CardException;
7
use Arcanedev\Stripe\Exceptions\InvalidRequestException;
8
use Arcanedev\Stripe\Exceptions\RateLimitException;
9
10
/**
11
 * Class     ErrorsHandler
12
 *
13
 * @package  Arcanedev\Stripe\Utilities
14
 * @author   ARCANEDEV <[email protected]>
15
 */
16
class ErrorsHandler implements ApiErrorsHandlerInterface
17
{
18
    /* ------------------------------------------------------------------------------------------------
19
     |  Properties
20
     | ------------------------------------------------------------------------------------------------
21
     */
22
    /** @var string */
23
    private $respBody;
24
25
    /** @var int */
26
    private $respCode;
27
28
    /** @var array */
29
    protected $respHeaders;
30
31
    /** @var array */
32
    private $response   = [];
33
34
    /** @var array */
35
    private static $exceptions = [
36
        400 => 'InvalidRequestException',
37
        401 => 'AuthenticationException',
38
        402 => 'CardException',
39
        404 => 'InvalidRequestException',
40
        429 => 'RateLimitException',
41
        500 => 'ApiException',
42
    ];
43
44
    /* ------------------------------------------------------------------------------------------------
45
     |  Getters & Setters
46
     | ------------------------------------------------------------------------------------------------
47
     */
48
    /**
49
     * Set Response body (JSON).
50
     *
51
     * @param  string  $respBody
52
     *
53
     * @return self
54
     */
55 125
    private function setRespBody($respBody)
56
    {
57 125
        $this->respBody = $respBody;
58
59 125
        return $this;
60
    }
61
62
    /**
63
     * Set Response Code.
64
     *
65
     * @param  int  $respCode
66
     *
67
     * @return self
68
     */
69 125
    private function setRespCode($respCode)
70
    {
71 125
        $this->respCode = $respCode;
72
73 125
        return $this;
74
    }
75
76
    /**
77
     * Set Response Headers.
78
     *
79
     * @param  array  $respHeaders
80
     *
81
     * @return self
82
     */
83 125
    private function setRespHeaders($respHeaders)
84
    {
85 125
        $this->respHeaders = $respHeaders;
86
87 125
        return $this;
88
    }
89
90
    /**
91
     * Set Response.
92
     *
93
     * @param  array  $response
94
     *
95
     * @return self
96
     */
97 125
    private function setResponse($response)
98
    {
99 125
        $this->checkResponse($response);
100
101 120
        $this->response = $response;
102
103 120
        return $this;
104
    }
105
106
    /**
107
     * Get Exception class.
108
     *
109
     * @return string
110
     */
111 120
    private function getException()
112
    {
113 120
        return $this->getExceptionByCode(
114 120
            $this->hasException() ? $this->respCode : 500
115 96
        );
116
    }
117
118
    /**
119
     * Get Exception class by status code.
120
     *
121
     * @param  int  $code
122
     *
123
     * @return string
124
     */
125 120
    private function getExceptionByCode($code)
126
    {
127 120
        return '\\Arcanedev\\Stripe\\Exceptions\\' . self::$exceptions[$code];
128
    }
129
130
    /* ------------------------------------------------------------------------------------------------
131
     |  Main Functions
132
     | ------------------------------------------------------------------------------------------------
133
     */
134
    /**
135
     * Handle API Errors.
136
     *
137
     * @param  string  $respBody
138
     * @param  int     $respCode
139
     * @param  array   $respHeaders
140
     * @param  array   $response
141
     *
142
     * @throws ApiException
143
     * @throws AuthenticationException
144
     * @throws CardException
145
     * @throws InvalidRequestException
146
     * @throws RateLimitException
147
     */
148 834
    public function handle($respBody, $respCode, $respHeaders, $response)
149
    {
150 834
        if ($respCode >= 200 && $respCode < 300) {
151 769
            return;
152
        }
153
154 125
        $this->setRespBody($respBody);
155 125
        $this->setRespCode($respCode);
156 125
        $this->setRespHeaders($respHeaders);
157 125
        $this->setResponse($response);
158
159 120
        list($message, $type, $stripeCode, $params) = $this->parseResponseError();
160
161 120
        $exception = $this->getException();
162
163 120
        if ($this->respCode === 400 && $stripeCode === 'rate_limit') {
164 5
            $this->setRespCode(429);
165 5
            $exception = $this->getExceptionByCode(429);
166 4
        }
167
168 120
        throw new $exception(
169 96
            $message,
170 120
            $this->respCode,
171 96
            $type,
172 96
            $stripeCode,
173 120
            $this->respBody,
174 120
            $this->response,
175 96
            $params,
176 120
            $this->respHeaders
177 96
        );
178
    }
179
180
    /* ------------------------------------------------------------------------------------------------
181
     |  Check Functions
182
     | ------------------------------------------------------------------------------------------------
183
     */
184
    /**
185
     * Check Response.
186
     *
187
     * @param  mixed  $response
188
     *
189
     * @throws ApiException
190
     */
191 125
    private function checkResponse($response)
192
    {
193 125
        if ( ! $this->hasErrorResponse($response)) {
194 5
            $msg = str_replace([
195 5
                '{resp-body}',
196
                '{resp-code}'
197 4
            ], [
198 5
                $this->respBody,
199 5
                $this->respCode,
200 5
            ], 'Invalid response object from API: {resp-body} (HTTP response code was {resp-code})');
201
202 5
            throw new ApiException($msg, $this->respCode, $this->respBody, $response);
203
        }
204 120
    }
205
206
    /**
207
     * Check if has Response.
208
     *
209
     * @param  mixed  $response
210
     *
211
     * @return bool
212
     */
213 125
    private function hasErrorResponse($response)
214
    {
215 125
        return is_array($response) && isset($response['error']);
216
    }
217
218
    /**
219
     * Check if has Exception.
220
     *
221
     * @return bool
222
     */
223 120
    private function hasException()
224
    {
225 120
        return array_key_exists($this->respCode, self::$exceptions);
226
    }
227
228
    /* ------------------------------------------------------------------------------------------------
229
     |  Other Functions
230
     | ------------------------------------------------------------------------------------------------
231
     */
232
    /**
233
     * Parse response error.
234
     *
235
     * @return array
236
     */
237 120
    private function parseResponseError()
238
    {
239
        return [
240 120
            $this->getResponseError('message'),
241 120
            $this->getResponseError('type'),
242 120
            $this->getResponseError('code'),
243 120
            $this->getResponseError('param'),
244 96
        ];
245
    }
246
247
    /**
248
     * Get Error attribute.
249
     *
250
     * @param  string  $name
251
     *
252
     * @return mixed
253
     */
254 120
    private function getResponseError($name)
255
    {
256 120
        $error = null;
257
258 120
        if (isset($this->response['error'][$name])) {
259 115
            $error   = $this->response['error'][$name];
260 92
        }
261
262 120
        if ($name === 'param' && is_null($error)) {
263 50
            $ignored = ['type', 'message', 'code'];
264 50
            $error   = array_diff_key($this->response['error'], array_flip($ignored));
265 40
        }
266
267 120
        return $error;
268
    }
269
}
270