Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit 073b546

Browse files
Refactor SDK to improve error handling and simplify logic
Enhanced exception handling by updating UnitException and integrating `Throwable` for better error context. Refactored the use of `HttpMethodsEnum` and introduced `ApiPathEnum` to streamline API path references. Added `isConnected` and `reset` methods to improve functionality and consolidated HTTP client setup in `UnitRequest`. Removed readonly attribute from `Certificate` class for future extensibility.
1 parent b2d19ae commit 073b546

File tree

6 files changed

+103
-42
lines changed

6 files changed

+103
-42
lines changed

src/Certificate.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* @implements CertificateInterface
1515
*/
16-
readonly class Certificate implements CertificateInterface, Arrayable
16+
class Certificate implements CertificateInterface, Arrayable
1717
{
1818
/**
1919
* @var array $chain

src/Config.php

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
namespace UnitPhpSdk;
44

55
use Override;
6+
use Throwable;
67
use UnitPhpSdk\Abstract\AbstractApplication;
78
use UnitPhpSdk\Config\{AccessLog, Listener, Route, Settings, Upstream, Upstream\Server};
89
use UnitPhpSdk\Exceptions\{FileNotFoundException, UnitException};
910
use UnitPhpSdk\Builders\ApplicationBuilder;
1011
use UnitPhpSdk\Builders\EndpointBuilder;
1112
use UnitPhpSdk\Contracts\ConfigInterface;
1213
use UnitPhpSdk\Contracts\Uploadable;
14+
use UnitPhpSdk\Enums\ApiPathEnum;
1315
use UnitPhpSdk\Http\UnitRequest;
1416
use UnitPhpSdk\Enums\HttpMethodsEnum;
1517
use UnitPhpSdk\Traits\CanUpload;
@@ -73,7 +75,7 @@ public function __construct(object $data = null, UnitRequest $unitRequest = null
7375
$this->parseUnitObject($data);
7476
}
7577

76-
$this->setApiEndpoint(EndpointBuilder::create('/config')->get());
78+
$this->setApiEndpoint(EndpointBuilder::create(ApiPathEnum::CONFIG->value)->get());
7779
}
7880

7981
/**
@@ -253,7 +255,7 @@ public function getListenerByPort(int $port): Listener|null
253255
public function uploadListener(Listener $listener): bool
254256
{
255257
try {
256-
$this->unitRequest->setMethod(HttpMethodsEnum::PUT->value)
258+
$this->unitRequest->setMethod(HttpMethodsEnum::PUT)
257259
->send("/config/listeners/{$listener->getListener()}", requestOptions: [
258260
'json' => $listener->toArray()
259261
]);
@@ -281,7 +283,7 @@ public function uploadListenerFromFile(string $path, string $listener): bool
281283
}
282284

283285
try {
284-
$this->unitRequest->setMethod('PUT')
286+
$this->unitRequest->setMethod(HttpMethodsEnum::PUT)
285287
->send("/config/listeners/$listener", requestOptions: [
286288
'body' => $fileContent
287289
]);
@@ -441,8 +443,8 @@ public function removeRoutes(): bool
441443
}
442444

443445
try {
444-
$this->unitRequest->setMethod(HttpMethodsEnum::DELETE->value)
445-
->send('/config/routes');
446+
$this->unitRequest->setMethod(HttpMethodsEnum::DELETE)
447+
->send(ApiPathEnum::ROUTES->value);
446448
} catch (UnitException) {
447449
return false;
448450
}
@@ -543,7 +545,7 @@ public function setAccessLog($path, $format = null): bool
543545
}
544546

545547
try {
546-
$this->unitRequest->setMethod(HttpMethodsEnum::PUT->value)
548+
$this->unitRequest->setMethod(HttpMethodsEnum::PUT)
547549
->send('/config/access_log', requestOptions: [
548550
'json' => json_encode($data)
549551
]);
@@ -554,15 +556,20 @@ public function setAccessLog($path, $format = null): bool
554556
return true;
555557
}
556558

559+
/**
560+
* Add access log to config
561+
*
562+
* @return AccessLog|null
563+
*/
557564
public function getAccessLog(): ?AccessLog
558565
{
559566
try {
560-
$result = $this->unitRequest->send('/config/access_log');
561-
} catch (UnitException) {
562-
return null;
563-
}
567+
$result = $this->unitRequest->send(ApiPathEnum::ACCESS_LOG->value);
564568

565-
return new AccessLog($result);
569+
return new AccessLog($result);
570+
} catch (Throwable $exception) {
571+
throw new UnitException($exception->getMessage(), $exception->getCode(), $exception);
572+
}
566573
}
567574

568575
public function removeAccessLog(): bool
@@ -612,6 +619,32 @@ private function mapConfigObjectToArray(array $data): array
612619
return array_combine($keys, $values);
613620
}
614621

622+
public function reset(): bool
623+
{
624+
try {
625+
$this->unitRequest->setMethod(HttpMethodsEnum::DELETE)
626+
->send('/config');
627+
628+
$this->unitRequest->setMethod(HttpMethodsEnum::POST)
629+
->send(
630+
uri: '/config',
631+
requestOptions: [
632+
'json' => json_encode([
633+
'listeners' => (object)[],
634+
'routes' => (object)[],
635+
'applications' => (object)[],
636+
'upstreams' => (object)[],
637+
'settings' => (object)[]
638+
])
639+
]
640+
);
641+
} catch (UnitException) {
642+
return false;
643+
}
644+
645+
return true;
646+
}
647+
615648
/**
616649
* @return Settings|null
617650
*/

src/Contracts/UnitInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function getCertificate(string $certificateName): ?CertificateInterface;
5252
* @return bool
5353
* @throws UnitException
5454
*/
55-
public function uploadCertificate(string $path, string $certificateName): bool;
55+
public function uploadCertificate(string $path, string $certificateName);
5656

5757
/**
5858
* Return full config uploaded on Nginx Unit

src/Exceptions/UnitException.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,26 @@
33
namespace UnitPhpSdk\Exceptions;
44

55
use Exception;
6+
use Throwable;
67

78
/**
89
* The UnitException class is an exception class that extends the base Exception class.
910
* It is used to represent exceptions that occur specifically within units.
10-
*
11-
* @package Your\Namespace
1211
*/
1312
class UnitException extends Exception
1413
{
1514
/**
1615
* Constructor method.
1716
*
18-
* @param string $message The message to be set for the object.
19-
*
20-
* @return void
17+
* @param string $message The exception message
18+
* @param int $code The exception code
19+
* @param Throwable|null $previous Previous throwable used for exception chaining
2120
*/
22-
public function __construct(string $message)
23-
{
24-
parent::__construct($message);
21+
public function __construct(
22+
string $message = "",
23+
int $code = 0,
24+
?Throwable $previous = null
25+
) {
26+
parent::__construct($message, $code, $previous);
2527
}
2628
}

src/Http/UnitRequest.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace UnitPhpSdk\Http;
44

55
use GuzzleHttp\Client;
6+
use GuzzleHttp\ClientInterface;
67
use GuzzleHttp\Exception\GuzzleException;
78
use UnitPhpSdk\Enums\HttpMethodsEnum;
89
use UnitPhpSdk\Exceptions\UnitException;
@@ -24,6 +25,8 @@ class UnitRequest
2425
*/
2526
private readonly string $address;
2627

28+
private ClientInterface $client;
29+
2730
/**
2831
* Constructor
2932
*
@@ -34,6 +37,11 @@ public function __construct(
3437
string $address,
3538
private readonly ?string $socket = null
3639
) {
40+
$this->client = $client ?? new Client([
41+
'base_uri' => $address,
42+
'curl' => $this->socket ? [CURLOPT_UNIX_SOCKET_PATH => $this->socket] : []
43+
]);
44+
3745
$this->address = $this->parseAddress($address);
3846
}
3947

@@ -71,21 +79,16 @@ public function setMethod(string|HttpMethodsEnum $method): self
7179
/**
7280
* Send request
7381
*
82+
* @param $uri
83+
* @param bool $associative
84+
* @param array $requestOptions
85+
* @return mixed
86+
* @throws GuzzleException
7487
* @throws UnitException
7588
*/
76-
public function send($uri, $associative = true, array $requestOptions = [])
89+
public function send($uri, bool $associative = true, array $requestOptions = [])
7790
{
78-
$client = new Client();
79-
80-
if (!empty($this->socket)) {
81-
$requestOptions['curl'] = [CURLOPT_UNIX_SOCKET_PATH => $this->socket];
82-
}
83-
84-
try {
85-
$response = $client->request($this->method, $this->address . $uri, $requestOptions);
86-
} catch (GuzzleException $exception) {
87-
throw new UnitException($exception->getMessage());
88-
}
91+
$response = $this->client->request($this->method, $this->address . $uri, $requestOptions);
8992

9093
$rawData = json_decode($response->getBody()->getContents(), $associative);
9194

src/Unit.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
namespace UnitPhpSdk;
44

55
use UnitPhpSdk\Contracts\{CertificateInterface, UnitInterface, Uploadable};
6+
use GuzzleHttp\Client;
67
use Override;
8+
use Psr\Http\Client\ClientInterface;
79
use UnitPhpSdk\Abstract\AbstractApplication;
8-
use UnitPhpSdk\Enums\HttpMethodsEnum;
910
use UnitPhpSdk\Exceptions\FileNotFoundException;
1011
use UnitPhpSdk\Exceptions\UnitException;
1112
use UnitPhpSdk\Http\UnitRequest;
@@ -47,14 +48,15 @@ class Unit implements UnitInterface
4748

4849
private UnitRequest $request;
4950

51+
5052
/**
5153
* Constructor
5254
*
5355
* @throws UnitException
5456
*/
5557
public function __construct(
5658
private readonly string $address,
57-
private readonly ?string $socket = null
59+
private readonly ?string $socket = null,
5860
) {
5961
$this->request = new UnitRequest(
6062
address: $this->address,
@@ -84,6 +86,7 @@ public function getConfig(): Contracts\ConfigInterface
8486
private function loadConfig(): void
8587
{
8688
$result = $this->request->send('/config', false);
89+
// dd($result);
8790
$this->config = new Config($result, $this->request);
8891
}
8992

@@ -101,7 +104,7 @@ public function getCertificates(): array
101104
/**
102105
* @inheritDoc
103106
*/
104-
public function uploadCertificate(string $path, string $certificateName): bool
107+
public function uploadCertificate(string $path, string $certificateName)
105108
{
106109
// TODO: need to review
107110
$fileContent = file_get_contents($path);
@@ -115,12 +118,13 @@ public function uploadCertificate(string $path, string $certificateName): bool
115118
->send("/certificates/$certificateName", requestOptions: [
116119
'body' => $fileContent
117120
]);
118-
} catch (UnitException $exception) {
119-
print_r($exception->getMessage());
120-
return false;
121-
}
121+
} catch (\Throwable $exception) {
122+
if ($exception->getCode() == 400) {
123+
throw new UnitException($exception->getMessage());
124+
}
122125

123-
return true;
126+
throw new UnitException($exception->getMessage());
127+
}
124128
}
125129

126130
/**
@@ -213,7 +217,7 @@ private function loadJsModules(): void
213217
*/
214218
private function loadStatistics(): void
215219
{
216-
$result = (new UnitRequest($this->address, $this->socket))->send('/status');
220+
$result = $this->request->send('/status');
217221
$this->statistics = new Statistics($result);
218222
}
219223

@@ -302,6 +306,9 @@ public function restartApplication(AbstractApplication $application): bool
302306
return true;
303307
}
304308

309+
/**
310+
* @throws UnitException
311+
*/
305312
#[Override] public function toArray(): array
306313
{
307314
return [
@@ -312,6 +319,22 @@ public function restartApplication(AbstractApplication $application): bool
312319
];
313320
}
314321

322+
/**
323+
* Checks if a connection to the server is established.
324+
*
325+
* @return bool Returns true if the connection is successful, false otherwise.
326+
*/
327+
public function isConnected(): bool
328+
{
329+
try {
330+
$this->request->send('/');
331+
} catch (UnitException) {
332+
return false;
333+
}
334+
335+
return true;
336+
}
337+
315338
#[Override] public function toJson(int $options = 0): string
316339
{
317340
return json_encode($this->toArray(), $options);

0 commit comments

Comments
 (0)