Skip to content

Commit eada1e5

Browse files
authored
Merge pull request #3 from KroderDev/codex/check-api-response-handling-in-model
Handle failed API responses in model operations
2 parents 71bd69e + cb481f8 commit eada1e5

File tree

2 files changed

+196
-6
lines changed

2 files changed

+196
-6
lines changed

src/Models/Model.php

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,22 @@ public static function updateById($id, array $attributes): bool
139139
$method = strtolower(config('microservice.models.update_method', 'put'));
140140
$response = static::client()->{$method}(static::endpoint().'/'.$id, $attributes);
141141

142-
if (is_object($response) && method_exists($response, 'successful')) {
143-
return $response->successful();
142+
if (is_object($response)) {
143+
if (method_exists($response, 'successful')) {
144+
return $response->successful();
145+
}
146+
147+
if (method_exists($response, 'status')) {
148+
$status = $response->status();
149+
150+
return $status >= 200 && $status < 300;
151+
}
152+
153+
if (method_exists($response, 'getStatusCode')) {
154+
$status = $response->getStatusCode();
155+
156+
return $status >= 200 && $status < 300;
157+
}
144158
}
145159

146160
return true;
@@ -160,6 +174,28 @@ public function update(array $attributes = [], array $options = []): bool
160174
$method = strtolower(config('microservice.models.update_method', 'put'));
161175
$response = static::client()->{$method}(static::endpoint().'/'.$this->getKey(), $this->attributesToArray());
162176

177+
if (is_object($response)) {
178+
if (method_exists($response, 'successful') && ! $response->successful()) {
179+
return false;
180+
}
181+
182+
if (method_exists($response, 'status')) {
183+
$status = $response->status();
184+
185+
if ($status < 200 || $status >= 300) {
186+
return false;
187+
}
188+
}
189+
190+
if (method_exists($response, 'getStatusCode')) {
191+
$status = $response->getStatusCode();
192+
193+
if ($status < 200 || $status >= 300) {
194+
return false;
195+
}
196+
}
197+
}
198+
163199
$data = static::parseResponse($response);
164200
if ($fresh = static::fromResponse($data)) {
165201
$this->fill($fresh->attributesToArray());
@@ -182,9 +218,26 @@ public function updateOrFail(array $attributes = [], array $options = []): bool
182218

183219
$method = strtolower(config('microservice.models.update_method', 'put'));
184220
$response = static::client()->{$method}(static::endpoint().'/'.$this->getKey(), $this->attributesToArray());
221+
if (is_object($response)) {
222+
if (method_exists($response, 'successful') && ! $response->successful()) {
223+
throw new \RuntimeException('Update failed.');
224+
}
185225

186-
if (is_object($response) && method_exists($response, 'successful') && ! $response->successful()) {
187-
throw new \RuntimeException('Update failed.');
226+
if (method_exists($response, 'status')) {
227+
$status = $response->status();
228+
229+
if ($status < 200 || $status >= 300) {
230+
throw new \RuntimeException('Update failed with status '.$status.'.');
231+
}
232+
}
233+
234+
if (method_exists($response, 'getStatusCode')) {
235+
$status = $response->getStatusCode();
236+
237+
if ($status < 200 || $status >= 300) {
238+
throw new \RuntimeException('Update failed with status '.$status.'.');
239+
}
240+
}
188241
}
189242

190243
$data = static::parseResponse($response);
@@ -208,6 +261,28 @@ public function save(array $options = []): bool
208261
$response = static::client()->post(static::endpoint(), $this->attributesToArray());
209262
}
210263

264+
if (is_object($response)) {
265+
if (method_exists($response, 'successful') && ! $response->successful()) {
266+
return false;
267+
}
268+
269+
if (method_exists($response, 'status')) {
270+
$status = $response->status();
271+
272+
if ($status < 200 || $status >= 300) {
273+
return false;
274+
}
275+
}
276+
277+
if (method_exists($response, 'getStatusCode')) {
278+
$status = $response->getStatusCode();
279+
280+
if ($status < 200 || $status >= 300) {
281+
return false;
282+
}
283+
}
284+
}
285+
211286
$data = static::parseResponse($response);
212287
if ($fresh = static::fromResponse($data)) {
213288
$this->fill($fresh->attributesToArray());
@@ -225,9 +300,22 @@ public function delete(): bool
225300
{
226301
$method = strtolower(config('microservice.models.delete_method', 'delete'));
227302
$response = static::client()->{$method}(static::endpoint().'/'.$this->getKey());
303+
if (is_object($response)) {
304+
if (method_exists($response, 'successful')) {
305+
return $response->successful();
306+
}
307+
308+
if (method_exists($response, 'status')) {
309+
$status = $response->status();
228310

229-
if (is_object($response) && method_exists($response, 'successful')) {
230-
return $response->successful();
311+
return $status >= 200 && $status < 300;
312+
}
313+
314+
if (method_exists($response, 'getStatusCode')) {
315+
$status = $response->getStatusCode();
316+
317+
return $status >= 200 && $status < 300;
318+
}
231319
}
232320

233321
return true;

tests/Models/ApiModelTest.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,30 @@ public function delete_users_respects_configured_method()
238238
], $this->gateway->getCalls());
239239
}
240240

241+
/** @test */
242+
public function delete_returns_false_on_failed_response()
243+
{
244+
$this->gateway = new class () extends FakeGatewayClient {
245+
public function delete(string $uri)
246+
{
247+
parent::delete($uri);
248+
249+
return new class () {
250+
public function successful()
251+
{
252+
return false;
253+
}
254+
};
255+
}
256+
};
257+
$this->app->bind(ApiGatewayClientInterface::class, fn () => $this->gateway);
258+
259+
$user = new RemoteUser(['id' => 6]);
260+
$user->exists = true;
261+
262+
$this->assertFalse($user->delete());
263+
}
264+
241265
/** @test */
242266
public function static_update_users_gateway()
243267
{
@@ -258,6 +282,34 @@ public function put(string $uri, array $data = [])
258282
], $this->gateway->getCalls());
259283
}
260284

285+
/** @test */
286+
public function static_update_returns_false_on_failed_response()
287+
{
288+
$this->gateway = new class () extends FakeGatewayClient {
289+
public function put(string $uri, array $data = [])
290+
{
291+
parent::put($uri, $data);
292+
293+
return new class () {
294+
public function successful()
295+
{
296+
return false;
297+
}
298+
299+
public function json()
300+
{
301+
return [];
302+
}
303+
};
304+
}
305+
};
306+
$this->app->bind(ApiGatewayClientInterface::class, fn () => $this->gateway);
307+
308+
$result = RemoteUser::updateById(10, ['name' => 'Bad']);
309+
310+
$this->assertFalse($result);
311+
}
312+
261313
/** @test */
262314
public function instance_update_users_gateway()
263315
{
@@ -271,6 +323,56 @@ public function instance_update_users_gateway()
271323
], $this->gateway->getCalls());
272324
}
273325

326+
/** @test */
327+
public function update_returns_false_on_failed_response()
328+
{
329+
$this->gateway = new class () extends FakeGatewayClient {
330+
public function put(string $uri, array $data = [])
331+
{
332+
parent::put($uri, $data);
333+
334+
return new class () {
335+
public function successful()
336+
{
337+
return false;
338+
}
339+
340+
public function json()
341+
{
342+
return [];
343+
}
344+
};
345+
}
346+
};
347+
$this->app->bind(ApiGatewayClientInterface::class, fn () => $this->gateway);
348+
349+
$user = new RemoteUser(['id' => 12, 'name' => 'Old']);
350+
$user->exists = true;
351+
352+
$this->assertFalse($user->update(['name' => 'Fail']));
353+
}
354+
355+
/** @test */
356+
public function update_propagates_api_gateway_exceptions()
357+
{
358+
$this->gateway = new class () extends FakeGatewayClient {
359+
public function put(string $uri, array $data = [])
360+
{
361+
parent::put($uri, $data);
362+
363+
throw new \Kroderdev\LaravelMicroserviceCore\Exceptions\ApiGatewayException(500);
364+
}
365+
};
366+
$this->app->bind(ApiGatewayClientInterface::class, fn () => $this->gateway);
367+
368+
$user = new RemoteUser(['id' => 15, 'name' => 'Old']);
369+
$user->exists = true;
370+
371+
$this->expectException(\Kroderdev\LaravelMicroserviceCore\Exceptions\ApiGatewayException::class);
372+
373+
$user->update(['name' => 'Boom']);
374+
}
375+
274376
/** @test */
275377
public function find_or_fail_throws_when_not_found()
276378
{

0 commit comments

Comments
 (0)