Skip to content

Commit 361f1fe

Browse files
fix: Handle all exceptions within Guzzle feature requester (#226)
fixes #225 Co-authored-by: jsonbailey <[email protected]>
1 parent d22efb2 commit 361f1fe

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/LaunchDarkly/Impl/Integrations/GuzzleFeatureRequester.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace LaunchDarkly\Impl\Integrations;
66

7+
use Exception;
78
use GuzzleHttp\Client;
89
use GuzzleHttp\Exception\BadResponseException;
910
use GuzzleHttp\HandlerStack;
@@ -75,6 +76,9 @@ public function getFeature(string $key): ?FeatureFlag
7576
$this->handleUnexpectedStatus($code, "GuzzleFeatureRequester::get");
7677
}
7778
return null;
79+
} catch (Exception $e) {
80+
$this->_logger->error("GuzzleFeatureRequester::get encountered an exception retrieving flag key {$key}: " . $e->getMessage());
81+
return null;
7882
}
7983
}
8084

@@ -99,6 +103,9 @@ public function getSegment(string $key): ?Segment
99103
$this->handleUnexpectedStatus($code, "GuzzleFeatureRequester::get");
100104
}
101105
return null;
106+
} catch (Exception $e) {
107+
$this->_logger->error("GuzzleFeatureRequester::get encountered an exception retrieving segment key {$key}: " . $e->getMessage());
108+
return null;
102109
}
103110
}
104111

@@ -117,6 +124,9 @@ public function getAllFeatures(): ?array
117124
/** @psalm-suppress PossiblyNullReference (resolved in guzzle 7) */
118125
$this->handleUnexpectedStatus($e->getResponse()->getStatusCode(), "GuzzleFeatureRequester::getAll");
119126
return null;
127+
} catch (Exception $e) {
128+
$this->_logger->error("GuzzleFeatureRequester::getAll encountered an exception retrieving all flags: " . $e->getMessage());
129+
return null;
120130
}
121131
}
122132

tests/Impl/Integrations/GuzzleFeatureRequesterTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,37 @@ public function testSendsCorrectWrapperNameHeaders(?string $wrapper_name, ?strin
144144
$this->assertNotContains('X-LaunchDarkly-Wrapper', $headers);
145145
}
146146
}
147+
148+
public function testTimeoutReturnsDefaultValue(): void
149+
{
150+
/** @var LoggerInterface **/
151+
$logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
152+
153+
$config = [
154+
'logger' => $logger,
155+
'timeout' => 1, // Set a very short timeout
156+
'connect_timeout' => 1,
157+
];
158+
159+
$client = new Client();
160+
// Configure the mock server to delay the response by 2 seconds
161+
$delayRule = [
162+
'request' => [
163+
'url' => '/sdk/flags/delayed-flag',
164+
],
165+
'response' => [
166+
'fixedDelayMilliseconds' => 2000,
167+
'status' => 200,
168+
'body' => '{"key": "delayed-flag", "version": 1}'
169+
]
170+
];
171+
172+
$client->request('POST', 'http://localhost:8080/__admin/mappings', ['json' => $delayRule]);
173+
174+
$requester = new GuzzleFeatureRequester('http://localhost:8080', 'sdk-key', $config);
175+
$result = $requester->getFeature("delayed-flag");
176+
177+
// The request should timeout and return null (default value) instead of throwing an exception
178+
$this->assertNull($result);
179+
}
147180
}

0 commit comments

Comments
 (0)