Skip to content

Commit 36ed18a

Browse files
gsousadevgsousadev
andauthored
feat: Criando exception padronizada de Unexpected Error (#4)
* feat: Criando exception padronizada de Unexpected Error * feat: documentando classe de exceptions inesperadas * fix: Ajustando Versão na doc --------- Co-authored-by: gsousadev <[email protected]>
1 parent 1d94646 commit 36ed18a

File tree

3 files changed

+94
-7
lines changed

3 files changed

+94
-7
lines changed

README.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Laravel Problem Detail Exceptions
22

3-
[![Versão](https://img.shields.io/badge/vers%C3%A3o-1.0.1-beta)](https://github.com/seu-usuario/sua-lib/releases)
3+
[![Versão](https://img.shields.io/badge/vers%C3%A3o-1.1.0-beta)](https://github.com/seu-usuario/sua-lib/releases)
44
[![Licença](https://img.shields.io/badge/licen%C3%A7a-MIT-green)](https://opensource.org/licenses/MIT)
55

66
Esse projeto tem por objetivo prover uma biblioteca Laravel que permite implementar de maneira simples e rápida um padrão de exceptions, seguindo os conceitos da [RFC de problem details](https://datatracker.ietf.org/doc/html/rfc7807)
@@ -23,7 +23,7 @@ Após a publicação do pacote deve ser criado um arquivo de configuração para
2323

2424
## Configurando
2525

26-
Este pacote permite algumas configurações de customização. Para isso deve-se user o arquivo ```problem-detail-exceptions.php```
26+
Este pacote permite algumas configurações de customização. Para isso deve-se user o arquivo `problem-detail-exceptions.php`
2727

2828
Para ter dados coerentes dentro do fluxo é importante ter duas variáveis de ambiente implementadas:
2929
- **PROBLEM_DETAIL_EXCEPTION_APP_NAME** : Indica o nome que pode aparecer nos logs referente ao nome do projeto ou app que o pacote esta sendo usado.
@@ -61,7 +61,7 @@ enum ExceptionsFieldsEnum: string
6161
```
6262

6363

64-
## Usando
64+
## Criando Exceptions Customizadas
6565

6666
Para usar o pacote recomendamos que sejam criadas excessões extendendo da classe `Gsousadev\LaravelProblemDetailExceptions\Exceptions\ProblemDetailException` conforme a classe de exemplo abaixo:
6767

@@ -137,6 +137,47 @@ try {
137137
}
138138
```
139139

140+
## Padronizando Exceptions
141+
142+
Existe uma classe que pode ser usada em conjunto com o Handler de Exceptions do Laravel para permitir que todas as
143+
exceptions lançadas e que passem pelo handler possam ser transformadas e normalizadas no padrão 'Problem Detail'.
144+
Isso permite que a aplicação que tenham excetions em formatos diferentes possa rapidamente padronizar a saida dessas
145+
exceptions para Logs e Requisições HTTP. Geralmente o arquivo de Handler do laravel esta localizado aqui
146+
`App\Exceptions\Handler.php`. Podemos implementar a classe conforme o exemplo abaixo:
147+
148+
149+
```php
150+
151+
<?php
152+
153+
namespace App\Exceptions;
154+
155+
use Gsousadev\LaravelProblemDetailExceptions\Exceptions\ProblemDetailException;
156+
use Gsousadev\LaravelProblemDetailExceptions\Exceptions\UnexpectedException;
157+
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
158+
use Throwable;
159+
160+
class Handler extends ExceptionHandler
161+
{
162+
public function register()
163+
{
164+
$this->renderable(function (Throwable $e) {
165+
if (!$e instanceof ProblemDetailException) {
166+
throw new UnexpectedException($e);
167+
}
168+
});
169+
}
170+
171+
public function report(Throwable $e)
172+
{
173+
if ($e instanceof ProblemDetailException) {
174+
parent::report($e);
175+
}
176+
}
177+
}
178+
179+
```
180+
140181
## Contribuindo
141182

142183
O projeto esta em fase de construção da ideia inicial, mas apontamentos de melhorias são muito importantes para o
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gsousadev\LaravelProblemDetailExceptions\Exceptions;
6+
7+
use Symfony\Component\HttpFoundation\Response;
8+
9+
class UnexpectedException extends ProblemDetailException
10+
{
11+
public function __construct(
12+
\Throwable $e
13+
) {
14+
$details = [
15+
'exception_code' => $e->getCode(),
16+
'exception_line' => $e->getLine(),
17+
'exception_message' => $e->getMessage(),
18+
'exception_file' => $e->getFile()
19+
];
20+
21+
$statusCode = $this->getValidStatusCode($e);
22+
23+
parent::__construct(
24+
title : $statusCode == Response::HTTP_INTERNAL_SERVER_ERROR ? "Erro Inesperado" : $e->getMessage(),
25+
detail : json_encode($details),
26+
userTitle : 'Ocorreu um erro inesperado',
27+
userMessage : 'Entre em contato com o administrador do sistema',
28+
httpStatus : $statusCode,
29+
internalCode: "UNEXPECTED_ERROR",
30+
previous : $e
31+
);
32+
}
33+
34+
private function getValidStatusCode(\Throwable $e)
35+
{
36+
if (method_exists($e, 'getStatusCode') &&
37+
in_array($e->getStatusCode(), array_keys(Response::$statusTexts))) {
38+
return $e->getStatusCode();
39+
}
40+
41+
return in_array($e->getCode(), array_keys(Response::$statusTexts)) ?
42+
$e->getCode() :
43+
Response::HTTP_INTERNAL_SERVER_ERROR;
44+
}
45+
}

tests/Unit/ProblemDetailExceptionTest.php renamed to tests/Unit/ConfigTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,28 @@
44

55
use Gsousadev\LaravelProblemDetailExceptions\Enums\ExceptionsFieldsEnum;
66
use Gsousadev\LaravelProblemDetailExceptions\Exceptions\ServerException;
7+
use Gsousadev\LaravelProblemDetailExceptions\Exceptions\UnexpectedException;
78
use Orchestra\Testbench\TestCase;
89

9-
class ProblemDetailExceptionTest extends TestCase
10+
class ConfigTest extends TestCase
1011
{
1112
public function testShouldReturnFieldsByConfig()
1213
{
1314
config()->set('problem-detail-exceptions.app_name', 'TEST');
1415
config()->set('problem-detail-exceptions.enable_log_in_exception', false);
1516
config()->set('problem-detail-exceptions.available_fields_list', [
16-
ExceptionsFieldsEnum::MESSAGE,
17+
ExceptionsFieldsEnum::TITLE,
1718
ExceptionsFieldsEnum::STATUS
1819
]);
1920
config()->set('problem-detail-exceptions.renderable_fields_list', [
2021
ExceptionsFieldsEnum::STATUS
2122
]);
2223

23-
$exception = new ServerException();
24+
$exception = new UnexpectedException(new \Exception('Teste Erro Sem Mapeamento', 0));
2425

2526
$this->assertEquals(
2627
[
27-
'message' => 'Erro interno do servidor - O servidor encontrou um erro interno e não foi capaz de completar sua requisição',
28+
'title' => 'Erro Inesperado',
2829
'status' => '500'
2930
],
3031
$exception->toArray()

0 commit comments

Comments
 (0)