Skip to content

Commit 6a8b8ab

Browse files
Merge pull request #173 from acquia/LCH-6348
2 parents 7c6ae39 + 269a140 commit 6a8b8ab

File tree

6 files changed

+354
-99
lines changed

6 files changed

+354
-99
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"require": {
1717
"acquia/http-hmac-php": ">=3.4",
1818
"ext-json": "*",
19-
"php": ">=7.3",
19+
"php": ">=7.4",
2020
"psr/log": ">=1.0",
2121
"guzzlehttp/guzzle": ">=6.5",
2222
"symfony/event-dispatcher": ">=4.4",

src/ContentHubClientTrait.php

Lines changed: 2 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
namespace Acquia\ContentHubClient;
44

55
use Acquia\ContentHubClient\Guzzle\Middleware\RequestResponseHandler;
6+
use Acquia\ContentHubClient\Logging\LoggingHelperTrait;
67
use GuzzleHttp\HandlerStack;
7-
use GuzzleHttp\Promise\PromiseInterface;
8-
use GuzzleHttp\Psr7\Response;
98
use Psr\Http\Message\RequestInterface;
109
use Psr\Http\Message\ResponseInterface;
11-
use Psr\Log\LogLevel;
1210

1311
/**
1412
* Common trait for CH Client and CH Logging Client.
1513
*/
1614
trait ContentHubClientTrait {
1715

1816
use ContentHubClientCommonTrait;
17+
use LoggingHelperTrait;
1918

2019
/**
2120
* GuzzleHttp client.
@@ -24,13 +23,6 @@ trait ContentHubClientTrait {
2423
*/
2524
public $httpClient;
2625

27-
/**
28-
* The logger responsible for tracking request failures.
29-
*
30-
* @var \Psr\Log\LoggerInterface
31-
*/
32-
public $logger;
33-
3426
/**
3527
* Custom configurations.
3628
*
@@ -117,92 +109,6 @@ protected static function makePath(...$path_components): string { // phpcs:ignor
117109
return self::gluePartsTogether($path_components, '/');
118110
}
119111

120-
/**
121-
* Returns error response.
122-
*
123-
* @param int $code
124-
* Status code.
125-
* @param string $reason
126-
* Reason.
127-
* @param string|null $request_id
128-
* The request id from the ContentHub service if available.
129-
*
130-
* @return \GuzzleHttp\Psr7\Response
131-
* Response.
132-
*/
133-
protected function getErrorResponse($code, $reason, $request_id = NULL) {
134-
if ($code < 100 || $code >= 600) {
135-
$code = 500;
136-
}
137-
$body = [
138-
'request_id' => $request_id,
139-
'error' => [
140-
'code' => $code,
141-
'message' => $reason,
142-
],
143-
];
144-
return new Response($code, [], json_encode($body), '1.1', $reason);
145-
}
146-
147-
/**
148-
* Obtains the appropriate exception Response, logging error messages according to API call.
149-
*
150-
* @param string $method
151-
* The Request to Plexus, as defined in the content-hub-php library.
152-
* @param string $api_call
153-
* The api endpoint.
154-
* @param \Exception $exception
155-
* The Exception object.
156-
*
157-
* @return \Psr\Http\Message\ResponseInterface
158-
* The response after raising an exception.
159-
*
160-
* @codeCoverageIgnore
161-
*/
162-
protected function getExceptionResponse(string $method, string $api_call, \Exception $exception): ResponseInterface {
163-
// If we reach here it is because there was an exception raised in the API call.
164-
$response = $exception->getResponse();
165-
if (!$response) {
166-
$response = $this->getErrorResponse($exception->getCode(), $exception->getMessage());
167-
}
168-
$response_body = json_decode($response->getBody(), TRUE);
169-
$error_code = $response_body['error']['code'] ?? '';
170-
$error_message = $response_body['error']['message'] ?? $exception->getMessage();
171-
172-
// Customize Error messages according to API Call.
173-
switch ($api_call) {
174-
case'settings/webhooks':
175-
$log_level = LogLevel::WARNING;
176-
break;
177-
178-
case (preg_match('/filters\?name=*/', $api_call) ? TRUE : FALSE):
179-
case (preg_match('/settings\/clients\/*/', $api_call) ? TRUE : FALSE):
180-
case (preg_match('/settings\/webhooks\/.*\/filters/', $api_call) ? TRUE : FALSE):
181-
$log_level = LogLevel::NOTICE;
182-
break;
183-
184-
default:
185-
// The default log level is ERROR.
186-
$log_level = LogLevel::ERROR;
187-
break;
188-
}
189-
190-
$reason = sprintf("Request ID: %s, Method: %s, Path: \"%s\", Status Code: %s, Reason: %s, Error Code: %s, Error Message: \"%s\". Error data: \"%s\"",
191-
$response_body['request_id'] ?? '',
192-
strtoupper($method),
193-
$api_call,
194-
$response->getStatusCode(),
195-
$response->getReasonPhrase(),
196-
$error_code,
197-
$error_message,
198-
print_r($response_body['error']['data'] ?? $response_body['error'] ?? '', TRUE)
199-
);
200-
$this->logger->log($log_level, $reason);
201-
202-
// Return the response.
203-
return $response;
204-
}
205-
206112
/**
207113
* Get the settings that were used to instantiate this client.
208114
*

src/Logging/LoggingHelperTrait.php

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<?php
2+
3+
namespace Acquia\ContentHubClient\Logging;
4+
5+
use GuzzleHttp\Psr7\Response;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Log\LoggerInterface;
8+
use Psr\Log\LogLevel;
9+
10+
/**
11+
* Helper trait for logging operations.
12+
*/
13+
trait LoggingHelperTrait {
14+
15+
/**
16+
* The logger service.
17+
*
18+
* @var \Psr\Log\LoggerInterface
19+
*/
20+
public LoggerInterface $logger;
21+
22+
/**
23+
* Obtains the appropriate exception Response, logging error messages according to API call.
24+
*
25+
* @param string $method
26+
* The Request to Plexus, as defined in the content-hub-php library.
27+
* @param string $api_call
28+
* The api endpoint.
29+
* @param \Exception $exception
30+
* The Exception object.
31+
*
32+
* @return \Psr\Http\Message\ResponseInterface
33+
* The response after raising an exception.
34+
*
35+
* @codeCoverageIgnore
36+
*/
37+
protected function getExceptionResponse(string $method, string $api_call, \Exception $exception): ResponseInterface {
38+
$response = $exception->getResponse();
39+
if (!$response) {
40+
$response = $this->getErrorResponse($exception->getCode(), $exception->getMessage());
41+
}
42+
$response_body = json_decode($response->getBody(), TRUE);
43+
$error_code = $response_body['error']['code'] ?? NULL;
44+
$error_message = $response_body['error']['message'] ?? $exception->getMessage();
45+
46+
$log_record = new RequestErrorLogParameter(
47+
LogLevel::ERROR,
48+
$response_body['request_id'] ?? '',
49+
strtoupper($method),
50+
$api_call,
51+
$response->getStatusCode(),
52+
$response->getReasonPhrase(),
53+
$error_code,
54+
$error_message,
55+
print_r($response_body['error']['data'] ?? $response_body['error'] ?? '', TRUE),
56+
);
57+
58+
// Customize Error messages according to API Call.
59+
switch ($api_call) {
60+
case'settings/webhooks':
61+
$log_record->logLevel = LogLevel::WARNING;
62+
break;
63+
64+
case (preg_match('/filters\?name=*/', $api_call) ? TRUE : FALSE):
65+
case (preg_match('/settings\/clients\/*/', $api_call) ? TRUE : FALSE):
66+
case (preg_match('/settings\/webhooks\/.*\/filters/', $api_call) ? TRUE : FALSE):
67+
$log_record->logLevel = LogLevel::NOTICE;
68+
break;
69+
}
70+
71+
$reason = $this->getResponseReason($log_record);
72+
$this->logger->log($log_record->logLevel, $reason);
73+
74+
// Return the response.
75+
return $response;
76+
}
77+
78+
/**
79+
* Returns a response reason based on the handler.
80+
*
81+
* @param \Acquia\ContentHubClient\Logging\RequestErrorLogParameter $record
82+
* The log record parameter object.
83+
*
84+
* @return string
85+
* The formatted log record.
86+
*/
87+
protected function getResponseReason(RequestErrorLogParameter $record): string {
88+
switch ($record) {
89+
case $record->getStatusCode() === 404:
90+
return $this->get404ResponseReason($record);
91+
92+
default:
93+
return $this->getDefaultResponseReason($record);
94+
}
95+
}
96+
97+
/**
98+
* Returns a formatted response reason based on the 404 status code.
99+
*
100+
* @return string
101+
* The reason.
102+
*/
103+
protected function get404ResponseReason(RequestErrorLogParameter $record): string {
104+
$record->logLevel = LogLevel::WARNING;
105+
return sprintf('Resource not found in Content Hub: %s.',
106+
$record->getApiCall(),
107+
);
108+
}
109+
110+
/**
111+
* Returns a default reason.
112+
*
113+
* @param \Acquia\ContentHubClient\Logging\RequestErrorLogParameter $record
114+
* The log record parameter object.
115+
*
116+
* @return string
117+
* The formatted reason.
118+
*/
119+
protected function getDefaultResponseReason(RequestErrorLogParameter $record): string {
120+
return sprintf('Request ID: %s, Method: %s, Path: "%s", Status Code: %s, Reason: %s, Error Code: %s, Error Message: "%s". Error data: "%s"',
121+
$record->getRequestId(),
122+
$record->getMethod(),
123+
$record->getApiCall(),
124+
$record->getStatusCode(),
125+
$record->getReasonPhrase(),
126+
$record->getErrorCode(),
127+
$record->getErrorMessage(),
128+
$record->getMetadata(),
129+
);
130+
}
131+
132+
/**
133+
* Returns error response.
134+
*
135+
* @param int $code
136+
* Status code.
137+
* @param string $reason
138+
* Reason.
139+
* @param string|null $request_id
140+
* The request id from the ContentHub service if available.
141+
*
142+
* @return \Psr\Http\Message\ResponseInterface
143+
* Response.
144+
*/
145+
protected function getErrorResponse(int $code, string $reason, ?string $request_id = NULL): ResponseInterface {
146+
if ($code < 100 || $code >= 600) {
147+
$code = 500;
148+
}
149+
$body = [
150+
'request_id' => $request_id,
151+
'error' => [
152+
'code' => $code,
153+
'message' => $reason,
154+
],
155+
];
156+
return new Response($code, [], json_encode($body), '1.1', $reason);
157+
}
158+
159+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
// phpcs:ignoreFile
3+
namespace Acquia\ContentHubClient\Logging;
4+
5+
/**
6+
* Parameter object, represents a log record.
7+
*/
8+
final class RequestErrorLogParameter {
9+
10+
public string $logLevel;
11+
private string $requestId;
12+
private string $method;
13+
private string $apiCall;
14+
private int $statusCode;
15+
private string $reasonPhrase;
16+
private ?int $errorCode;
17+
private string $errorMessage;
18+
private string $metadata;
19+
20+
public function __construct(
21+
string $log_level,
22+
string $request_id,
23+
string $method,
24+
string $api_call,
25+
int $status_code,
26+
string $reason_phrase,
27+
?int $error_code,
28+
string $error_message,
29+
string $metadata
30+
) {
31+
$this->logLevel = $log_level;
32+
$this->requestId = $request_id;
33+
$this->method = $method;
34+
$this->apiCall = $api_call;
35+
$this->statusCode = $status_code;
36+
$this->reasonPhrase = $reason_phrase;
37+
$this->errorCode = $error_code;
38+
$this->errorMessage = $error_message;
39+
$this->metadata = $metadata;
40+
}
41+
42+
/**
43+
* @return string
44+
*/
45+
public function getRequestId(): string {
46+
return $this->requestId;
47+
}
48+
49+
/**
50+
* @return string
51+
*/
52+
public function getMethod(): string {
53+
return $this->method;
54+
}
55+
56+
/**
57+
* @return string
58+
*/
59+
public function getApiCall(): string {
60+
return $this->apiCall;
61+
}
62+
63+
/**
64+
* @return int
65+
*/
66+
public function getStatusCode(): int {
67+
return $this->statusCode;
68+
}
69+
70+
/**
71+
* @return string
72+
*/
73+
public function getReasonPhrase(): string {
74+
return $this->reasonPhrase;
75+
}
76+
77+
/**
78+
* @return int|null
79+
*/
80+
public function getErrorCode(): ?int {
81+
return $this->errorCode;
82+
}
83+
84+
/**
85+
* @return string
86+
*/
87+
public function getErrorMessage(): string {
88+
return $this->errorMessage;
89+
}
90+
91+
/**
92+
* @return string
93+
*/
94+
public function getMetadata(): string {
95+
return $this->metadata;
96+
}
97+
98+
}

0 commit comments

Comments
 (0)