Skip to content

Commit f72aaf8

Browse files
authored
Merge pull request #174 from RonasIT/163-modify-500-code-error-response-page
163 modify 500 code error response page
2 parents 4ec8d4d + 5d00c6d commit f72aaf8

File tree

66 files changed

+2239
-194
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2239
-194
lines changed

.github/workflows/run-tests-with-coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Install Dependencies
2525
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
2626
- name: Execute unit tests via PHPUnit with coverage
27-
run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml
27+
run: php -d zend.exception_ignore_args=0 -d xdebug.collect_params=4 vendor/bin/phpunit --coverage-clover build/logs/clover.xml
2828
- name: Export coverage report
2929
if: ${{ matrix.php-version == '8.4' }}
3030
uses: actions/upload-artifact@v4

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"orchestra/testbench": ">=9.3",
2525
"php-coveralls/php-coveralls": "^2.7",
2626
"php-mock/php-mock-phpunit": ">=2.10",
27-
"ronasit/laravel-helpers": "^3.4"
27+
"ronasit/laravel-helpers": "^3.5"
2828
},
2929
"autoload": {
3030
"psr-4": {

composer.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/views/error.blade.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1-
{{ $message }}
1+
# ❗️ **ERROR** ❗️
2+
3+
## 🚨🚨 {{ $type }} 🚨🚨
4+
5+
---
6+
7+
### **Details:**
8+
9+
{{ $message }}
10+
11+
### **Error place:**
12+
13+
{{ $error_place }}
14+
---

src/Drivers/LocalDriver.php

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

55
use RonasIT\AutoDoc\Exceptions\FileNotFoundException;
66
use RonasIT\AutoDoc\Exceptions\MissedProductionFilePathException;
7+
use RonasIT\AutoDoc\Exceptions\EmptyDocFileException;
8+
use RonasIT\AutoDoc\Exceptions\NonJSONDocFileException;
9+
use Symfony\Component\Filesystem\Path;
710

811
class LocalDriver extends BaseDriver
912
{
@@ -35,6 +38,14 @@ public function getDocumentation(): array
3538

3639
$fileContent = file_get_contents($this->prodFilePath);
3740

41+
if (empty($fileContent)) {
42+
throw new EmptyDocFileException(Path::makeRelative($this->prodFilePath, base_path()));
43+
}
44+
45+
if (!json_validate($fileContent)) {
46+
throw new NonJSONDocFileException(Path::makeRelative($this->prodFilePath, base_path()));
47+
}
48+
3849
return json_decode($fileContent, true);
3950
}
4051
}

src/Drivers/RemoteDriver.php

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

55
use RonasIT\AutoDoc\Exceptions\FileNotFoundException;
66
use RonasIT\AutoDoc\Exceptions\MissedRemoteDocumentationUrlException;
7+
use RonasIT\AutoDoc\Exceptions\NonJSONDocFileException;
78

89
class RemoteDriver extends BaseDriver
910
{
@@ -39,6 +40,10 @@ public function getDocumentation(): array
3940
throw new FileNotFoundException();
4041
}
4142

43+
if (!json_validate($content)) {
44+
throw new NonJSONDocFileException('Remote documentation');
45+
}
46+
4247
return json_decode($content, true);
4348
}
4449

src/Drivers/StorageDriver.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Illuminate\Contracts\Filesystem\Filesystem;
77
use Illuminate\Support\Facades\Storage;
88
use RonasIT\AutoDoc\Exceptions\MissedProductionFilePathException;
9+
use RonasIT\AutoDoc\Exceptions\EmptyDocFileException;
10+
use RonasIT\AutoDoc\Exceptions\NonJSONDocFileException;
911

1012
class StorageDriver extends BaseDriver
1113
{
@@ -39,6 +41,14 @@ public function getDocumentation(): array
3941

4042
$fileContent = $this->disk->get($this->prodFilePath);
4143

44+
if (empty($fileContent)) {
45+
throw new EmptyDocFileException($this->prodFilePath);
46+
}
47+
48+
if (!json_validate($fileContent)) {
49+
throw new NonJSONDocFileException($this->prodFilePath);
50+
}
51+
4252
return json_decode($fileContent, true);
4353
}
4454
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace RonasIT\AutoDoc\Exceptions;
4+
5+
use Exception;
6+
7+
class NonJSONDocFileException extends Exception
8+
{
9+
public function __construct(string $filename)
10+
{
11+
parent::__construct("Doc file '{$filename}' is not a json doc file.");
12+
}
13+
}

src/Services/SwaggerService.php

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
use RonasIT\AutoDoc\Traits\GetDependenciesTrait;
2424
use RonasIT\AutoDoc\Validators\SwaggerSpecValidator;
2525
use Symfony\Component\HttpFoundation\Response;
26-
use Exception;
26+
use Throwable;
2727

2828
/**
2929
* @property SwaggerDriverContract $driver
@@ -73,6 +73,10 @@ public function __construct(Container $container)
7373
$this->setDriver();
7474

7575
if (config('app.env') === 'testing') {
76+
// client must enter at least `contact.email` to generate a default `info` block
77+
// otherwise an exception will be called
78+
$this->checkEmail();
79+
7680
$this->container = $container;
7781

7882
$this->security = $this->config['security'];
@@ -134,12 +138,6 @@ protected function setDriver()
134138

135139
protected function generateEmptyData(?string $view = null, array $viewData = [], array $license = []): array
136140
{
137-
// client must enter at least `contact.email` to generate a default `info` block
138-
// otherwise an exception will be called
139-
if (!empty($this->config['info']) && !Arr::get($this->config, 'info.contact.email')) {
140-
throw new EmptyContactEmailException();
141-
}
142-
143141
if (empty($view) && !empty($this->config['info'])) {
144142
$view = $this->config['info']['description'];
145143
}
@@ -165,6 +163,13 @@ protected function generateEmptyData(?string $view = null, array $viewData = [],
165163
return $data;
166164
}
167165

166+
protected function checkEmail(): void
167+
{
168+
if (!empty($this->config['info']) && !Arr::get($this->config, 'info.contact.email')) {
169+
throw new EmptyContactEmailException();
170+
}
171+
}
172+
168173
protected function generateSecurityDefinition(): ?array
169174
{
170175
if (empty($this->security)) {
@@ -796,18 +801,6 @@ protected function getActionName($uri): string
796801
return Str::camel($action);
797802
}
798803

799-
/**
800-
* @deprecated method is not in use
801-
* @codeCoverageIgnore
802-
*/
803-
protected function saveTempData()
804-
{
805-
$exportFile = Arr::get($this->config, 'files.temporary');
806-
$data = json_encode($this->data);
807-
808-
file_put_contents($exportFile, $data);
809-
}
810-
811804
public function saveProductionData()
812805
{
813806
if (ParallelTesting::token()) {
@@ -831,8 +824,12 @@ public function getDocFileContent()
831824
$documentation = $this->driver->getDocumentation();
832825

833826
$this->openAPIValidator->validate($documentation);
834-
} catch (Exception $exception) {
835-
return $this->generateEmptyData($this->config['defaults']['error'], ['message' => $exception->getMessage()]);
827+
} catch (Throwable $exception) {
828+
return $this->generateEmptyData($this->config['defaults']['error'], [
829+
'message' => $exception->getMessage(),
830+
'type' => $exception::class,
831+
'error_place' => $this->getErrorPlace($exception),
832+
]);
836833
}
837834

838835
$additionalDocs = config('auto-doc.additional_paths', []);
@@ -852,6 +849,18 @@ public function getDocFileContent()
852849
return $documentation;
853850
}
854851

852+
protected function getErrorPlace(Throwable $exception): string
853+
{
854+
$firstTraceEntry = Arr::first($exception->getTrace());
855+
856+
$formattedTraceEntry = Arr::map(
857+
array: $firstTraceEntry,
858+
callback: fn ($value, $key) => $key . '=' . (is_array($value) ? json_encode($value) : $value),
859+
);
860+
861+
return implode(', ', $formattedTraceEntry);
862+
}
863+
855864
protected function camelCaseToUnderScore($input): string
856865
{
857866
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
@@ -973,7 +982,7 @@ protected function prepareInfo(?string $view = null, array $viewData = [], array
973982
if (!empty($view)) {
974983
$info['description'] = view($view, $viewData)->render();
975984
}
976-
985+
977986
return array_merge($this->config['info'], $info);
978987
}
979988

tests/AutoDocControllerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function testGetJSONDocumentationIsEmpty()
7575
$mock->expects($this->once());
7676

7777
config([
78-
'auto-doc.additional_paths' => ['tests/fixtures/AutoDocControllerTest/documentation__non_json.txt'],
78+
'auto-doc.additional_paths' => ['tests/fixtures/AutoDocControllerTest/empty_additional_documentation.json'],
7979
]);
8080

8181
$response = $this->json('get', '/auto-doc/documentation');

0 commit comments

Comments
 (0)