Completed
Pull Request — master (#18)
by ARCANEDEV
07:31
created

ErrorsHandler::hasErrorResponse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

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