Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status-Code Handling #99

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [Refactor CTClient:](https://github.com/5pm-HDH/churchtools-api/pull/83) transform inheritance from GuzzleClient to composition-relation
- [Move generated Doc-Files to `out`-Folder](https://github.com/5pm-HDH/churchtools-api/pull/89)
- [Create UpdatableMode-Interface for type safety](https://github.com/5pm-HDH/churchtools-api/pull/93)
- [Status-Code handling and Exception-handling](https://github.com/5pm-HDH/churchtools-api/pull/99)

### Fixed

Expand Down
7 changes: 6 additions & 1 deletion docs/out/CTLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

By default, there are two log types:

**File-Log:**
**File-Log (Info):**

- Logs the log-levels: INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
- Log is stored to the file `churchtools-api.log`

**File-Log (Warning):**

- Logs the log-levels: WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
- Log is stored to the file `churchtools-api-warning.log`

**Console-Log:**

- Logs by default the log-level: ERROR, CRITICAL, ALERT, EMERGENCY
Expand Down
27 changes: 18 additions & 9 deletions docs/out/ErrorHandling.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@

The Error-Handling-Concept divides an exception in five different categories:

**CTConnectException**
## CTConfigException

- wrong Configuration (e.q. no API-Url is set)

## CTModelException

- exception in model (e.q. process wiki-pages return root node)

## CTRequestException

- could not retrieve the models

### CTConnectException extends CTRequestException

- technical Exception the ConnectException from Guzzle
- error in Connection (timeout, undefined-host, ...)

**CTConfigException**
- wrong Configuration (e.q. no API-Url is set)
### CTAuthException extends CTRequestException

**CTAuthException**
- could not authenticate user
- unauthorized access to resource

**CTRequestException**
- could not retrieve the models
### CTPermissionException extends CTRequestException

**CTModelException**
- exception in model (e.q. process wiki-pages return root node)
- unauthorized access to resource (401)
- forbidden api-call (403)
7 changes: 6 additions & 1 deletion docs/src/ressources/CTLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

By default, there are two log types:

**File-Log:**
**File-Log (Info):**

- Logs the log-levels: INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
- Log is stored to the file `churchtools-api.log`

**File-Log (Warning):**

- Logs the log-levels: WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
- Log is stored to the file `churchtools-api-warning.log`

**Console-Log:**

- Logs by default the log-level: ERROR, CRITICAL, ALERT, EMERGENCY
Expand Down
27 changes: 18 additions & 9 deletions docs/src/ressources/ErrorHandling.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@

The Error-Handling-Concept divides an exception in five different categories:

**CTConnectException**
## CTConfigException

- wrong Configuration (e.q. no API-Url is set)

## CTModelException

- exception in model (e.q. process wiki-pages return root node)

## CTRequestException

- could not retrieve the models

### CTConnectException extends CTRequestException

- technical Exception the ConnectException from Guzzle
- error in Connection (timeout, undefined-host, ...)

**CTConfigException**
- wrong Configuration (e.q. no API-Url is set)
### CTAuthException extends CTRequestException

**CTAuthException**
- could not authenticate user
- unauthorized access to resource

**CTRequestException**
- could not retrieve the models
### CTPermissionException extends CTRequestException

**CTModelException**
- exception in model (e.q. process wiki-pages return root node)
- unauthorized access to resource (401)
- forbidden api-call (403)
19 changes: 14 additions & 5 deletions src/CTClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
namespace CTApi;


use CTApi\Exceptions\CTAuthException;
use CTApi\Exceptions\CTConnectException;
use CTApi\Exceptions\CTPermissionException;
use CTApi\Exceptions\CTRequestException;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -72,17 +74,24 @@ public function delete($uri, array $options = []): ResponseInterface

private function handleResponse(ResponseInterface $response): ResponseInterface
{
switch ($response->getStatusCode()) {
case 401:
throw new CTAuthException("Unauthorized.", 401);
$responseCode = (int)$response->getStatusCode();
if ($responseCode == 401 || $responseCode == 403) {
throw new CTPermissionException("Unauthorized or Forbidden.", $responseCode);
}
return $response;

if ($responseCode >= 200 && $responseCode <= 299) {
return $response;
}

throw CTRequestException::ofErrorResponse($response);
}

private function handleException(Exception $exception): ResponseInterface
{
if ($exception instanceof ConnectException) {
throw new CTConnectException($exception->getMessage(), $exception->getCode(), $exception);
} else if ($exception instanceof GuzzleException) {
throw new CTRequestException($exception->getMessage(), $exception->getCode(), $exception);
}
throw $exception;
}
Expand Down
3 changes: 2 additions & 1 deletion src/CTConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace CTApi;

use CTApi\Exceptions\CTConfigException;
use CTApi\Exceptions\CTRequestException;
use CTApi\Middleware\CTCacheMiddleware;
use CTApi\Requests\AuthRequest;
use CTApi\Requests\PersonRequest;
Expand Down Expand Up @@ -107,7 +108,7 @@ public static function validateApiKey(): bool
} else {
return true;
}
} catch (\Exception $exception) {
} catch (CTRequestException $exception) {
return false;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/CTLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class CTLog
{
private const LOG_FILE = __DIR__ . '/../churchtools-api.log';
private const LOG_FILE_WARNING = __DIR__ . '/../churchtools-api-warning.log';

private static ?Logger $logger = null;
private static bool $fileLogEnabled = true;
Expand All @@ -35,6 +36,7 @@ private static function createLog(): void

if (self::$fileLogEnabled) {
self::$logger->pushHandler(new StreamHandler(self::LOG_FILE, Logger::INFO));
self::$logger->pushHandler(new StreamHandler(self::LOG_FILE_WARNING, Logger::WARNING));
}
if (self::$consoleLogEnabled) {
self::$logger->pushHandler(new StreamHandler('php://stdout', self::$consoleLogLevel));
Expand Down
7 changes: 5 additions & 2 deletions src/Exceptions/CTAuthException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
namespace CTApi\Exceptions;

use CTApi\CTLog;
use RuntimeException;
use Throwable;

class CTAuthException extends RuntimeException
/**
* Class CTAuthException is a CTRequestException. It Indicates a failed authentification.
* @package CTApi\Exceptions
*/
class CTAuthException extends CTRequestException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
{
Expand Down
4 changes: 4 additions & 0 deletions src/Exceptions/CTConfigException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use RuntimeException;
use Throwable;

/**
* Class CTConfigException indicates a error in the CTConfig-Settings.
* @package CTApi\Exceptions
*/
class CTConfigException extends RuntimeException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
Expand Down
7 changes: 5 additions & 2 deletions src/Exceptions/CTConnectException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@


use CTApi\CTLog;
use RuntimeException;
use Throwable;

class CTConnectException extends RuntimeException
/**
* Class CTConnectException is a CRRequestException. Its thrown when ChurchTools server is not available.
* @package CTApi\Exceptions
*/
class CTConnectException extends CTRequestException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
{
Expand Down
4 changes: 4 additions & 0 deletions src/Exceptions/CTModelException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use RuntimeException;
use Throwable;

/**
* Class CTModelException is thrown when the model data is invalid.
* @package CTApi\Exceptions
*/
class CTModelException extends RuntimeException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
Expand Down
21 changes: 21 additions & 0 deletions src/Exceptions/CTPermissionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php


namespace CTApi\Exceptions;


use CTApi\CTLog;
use Throwable;

/**
* Class CTPermissionException is a CTRequestException that indicates a permission error.
* @package CTApi\Exceptions
*/
class CTPermissionException extends CTRequestException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
CTLog::getLog()->warning("CTPermissionException: " . $message);
}
}
24 changes: 16 additions & 8 deletions src/Exceptions/CTRequestException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use RuntimeException;
use Throwable;

/**
* Class CTRequestException is thrown when communication with ChurchTools api fails.
* @package CTApi\Exceptions
*/
class CTRequestException extends RuntimeException
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
Expand All @@ -27,7 +31,7 @@ public static function ofModelNotFound(?string $modelName = null, ?Throwable $th

public static function ofErrorResponse(ResponseInterface $response): self
{
$contents = \json_decode((string) $response->getBody(), true);
$contents = \json_decode((string)$response->getBody(), true);

if (!isset($contents['message'])) {
return new self($response->getReasonPhrase() ?: 'Unknown API error.');
Expand All @@ -41,7 +45,7 @@ public static function ofErrorResponse(ResponseInterface $response): self
foreach ($contents['errors'] as $error) {
$wasValue = '';

if (array_key_exists('value', $error['args'])) {
if (array_key_exists('args', $error) && array_key_exists('value', $error['args'])) {
$wasValue = 'Received value was %s.';

if (is_null($error['args']['value'])) {
Expand All @@ -51,12 +55,16 @@ public static function ofErrorResponse(ResponseInterface $response): self
}
}

$errorDescriptions[] = sprintf(
'Field "%s": %s %s',
$error['fieldId'],
$error['message'],
$wasValue
);
if (array_key_exists('fieldId', $error)) {
$errorDescriptions[] = sprintf(
'Field "%s": %s %s',
$error['fieldId'],
$error['message'],
$wasValue
);
} else {
$errorDescriptions[] = $error['message'];
}
}

$msg .= '. ' . implode(' ', $errorDescriptions);
Expand Down
13 changes: 7 additions & 6 deletions src/Models/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use CTApi\CTClient;
use CTApi\CTConfig;
use CTApi\CTLog;
use CTApi\Exceptions\CTRequestException;
use CTApi\Models\Traits\FillWithData;
use CTApi\Models\Traits\MetaAttribute;
use GuzzleHttp\Exception\GuzzleException;
Expand Down Expand Up @@ -55,16 +56,16 @@ public function requestFileContent(): bool|string
{
try {
$baseUrl = $this->getFileUrlBaseUrl();
if(!is_null($baseUrl)){
if (!is_null($baseUrl)) {
$response = CTClient::getClient()->get($baseUrl, [
'headers' => [
'Cache-Control' => 'no-cache'
],
'query' => $this->getFileUrlQueryParameters()
]);
return (string) $response->getBody();
return (string)$response->getBody();
}
} catch (GuzzleException $e) {
} catch (CTRequestException $e) {
CTLog::getLog()->error('File: Could not retrieve file-content.');
// ignore
}
Expand All @@ -87,7 +88,7 @@ public function getFileUrlBaseUrl(): ?string
{
$fileUrlBase = null;

$parsedUrl = parse_url((string) $this->getFileUrl());
$parsedUrl = parse_url((string)$this->getFileUrl());
if (array_key_exists('scheme', $parsedUrl) && array_key_exists('host', $parsedUrl)) {
$fileUrlBase = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];

Expand All @@ -101,9 +102,9 @@ public function getFileUrlBaseUrl(): ?string
public function getFileUrlQueryParameters(): array
{
$query = [];
$parsedUrl = parse_url((string) $this->getFileUrl());
$parsedUrl = parse_url((string)$this->getFileUrl());
if (array_key_exists('query', $parsedUrl)) {
$queryString = (string) $parsedUrl['query'];
$queryString = (string)$parsedUrl['query'];

foreach (explode('&', $queryString) as $querySubstring) {
$querySubstringArray = explode('=', $querySubstring);
Expand Down
2 changes: 1 addition & 1 deletion src/Models/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function requestModifiedPerson(): ?Person

private function requestPerson(?string $id): ?Person
{
if (!is_null($id)) {
if (!is_null($id) && $id > 0) {
return PersonRequest::find((int)$id);
}
return null;
Expand Down
Loading