Completed
Pull Request — master (#29)
by ARCANEDEV
17:52
created

ErrorsHandler::setRespHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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