Do not speak Portuguese? Translate this site with Google or Bing Translator
Laravel Tratando exceções (Exceptions)

Posted on: August 30, 2021 10:39 PM

Posted by: Renato

Categories: Laravel PHP

Views: 6100

Laravel :: Tratando exceções (Exceptions)

*

Exceções no Laravel

Como desenvolvedor PHP, talvez use exceções por elas permitirem que você saiba quando algo errado aconteceu ou o quando o usuário agiu de forma não esperada (como tentar dividir números por zero) em sua aplicação. Sem o uso de exceções, sua aplicação acabaria apresentando erros indesejáveis e seria muito mais difícil de depurar. Também é importante pausar a execução e realizar outra ação em caso de exceção.

Exceções são simples de entender e facilitarão o progresso do seu desenvolvimento. Quando aprender a usar exceções, verá que elas serão algo comum no seu desenvolvimento.

O Que É uma Exceção?

Acredito que a melhor definição para exceções foi dita pelo Martin Fowler:

Exceções sinalizam algo fora do comportamento esperado de um dado trecho de código.

Mais precisamente, uma exceção é um evento que acontece durante a execução de um programa, quebrando o fluxo normal das instruções do mesmo. Quando você usa uma exceção (criando um objeto e passando para o sistema em execução) através do throw, o sistema irá capturá-la (através do catch) e buscará o manipulador de exceção adequado para ela e retornará a mensagem correta.

1
2
3
4
5
6
try {
    // the code goes here
} catch (Exception $e) {
    // if an exception happened in the try block above
 
}

Quando Precisamos Usar Exceções?

Use exceções quando se deparar com circunstâncias excepcionais que previnam a execução normal do sistema. Usamos exceções apenas quando o sistema não for capaz de determinar o que aconteceu. Martin Fowler acredita que "se uma falha é um comportamento esperado, não se deve usar exceção para ela". Isso significa que só deve, realmente, usar exceções quando não puder determinar o erro. Exceções deveriam ser usadas apenas em casos raros.

Nota: Exceções não são boas para manipular operações lógicas.

Para um sistema que valida dados de entrada, é errado usar exceções. Primeiro, o campo de texto é algo que conhecemos e, em uma aplicação como essa, devemos reportar um conjunto de erros ao invés de um único erro. Sou dos que acreditam que não se deve usar exceções em casos onde podemos esperar por erros de validação.

Capturar uma exceção é bastante importante, já que, caso isso ocorra, o sistema resultará em um erro. A operação de captura deve ser realizada tão logo quando a exceção ocorra.

Exceções no Laravel

O Laravel usa um manipulador de exceções, que é uma classe no arquivo App\Exceptions\Handler.php. Essa classe contém dois métodos principais (o método renderHttpException, que é usado para todas exceções HTTP, como os erros 404 e 503, fica na classe pai do manipulador). O primeiro é o report, que é usado para registrar exceções ou enviá-las para um serviço externo. Eis um exemplo do método report:

1
2
3
4
5
6
7
8
public function report(Exception $e)
{
    if ($e instanceof CustomException) {
        //
    }
 
    return parent::report($e);
}

O segundo é o render. O método render é responsável por converter uma dada exceção em uma resposta HTTP que deve ser enviada de volta para o navegador. Eis um exemplo do método render:

1
2
3
4
5
6
7
8
public function render($request, Exception $e)
{
    if ($e instanceof CustomException) {
        return response()->view('errors.custom', [], 500);
    }
 
    return parent::render($request, $e);
}

Nota: Você pode usar a propriedade $dontReport do manipulador de exceção para ignorar exceções de acordo com seus tipos.

Você pode sobrescrever os métodos de exceção do Laravel, com suas próprias exceções, dessa forma:

1
2
3
4
5
6
7
public function render($request, Exception $e)
{
    if (config('app.debug')) {
        return parent::render($request, $e);
    }
    return $this->handle($request, $e);
}

Isso será renderizado quando o modo de depuração estiver ativado.

Como Criar sua Prórpia Exceção no Laravel?

Talvez você tenha a necessidade de criar sua própria classe de exceção. Você precisará estender a classe base de Exceção do Laravel—criei uma classe abstrata que se comportará como a classe base para nossa classe de Exceção customizada. Crie o arquivo App/Exceptions/MyException.php:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace App\Exceptions;
use Exception;
abstract class monException extends Exception
{
    protected $id;
    protected $details;
     
    public function __construct($message)
    {
        parent::__construct($message);
    }
 
    protected function create(array $args)
    {
        $this->id = array_shift($args);
        $error = $this->errors($this->id);
        $this->details = vsprintf($error['context'], $args);
        return $this->details;
    }
 
    private function errors($id)
    {
        $data= [
            'not_found' => [
                'context'  => 'The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.',
            ]
            //   ...
        ];
        return $data[$id];
    }
}

E sua classe de Exceção:

1
2
3
4
5
6
7
8
9
namespace App\Exceptions;
class NotFoundmonException extends  monException
{
    public function __construct()
    {
        $message = $this->create(func_get_args());
        parent::__construct($message);
    }
}

Você pode usar a classe acima em seu código, assim:

1
2
3
4
5
6
7
try {
    throw new \App\Exceptions\NotFoundmonException('not_found');
}
catch(\App\Exceptions\NotFoundmonException $e)
{
    return $e->getMessage();
}

Além da classe de Exceção padrão do Laravel, você pode usar o pacote Assertion. Ele pode ser usado como uma classe de exceção de externa, de forma a evitar enormes quantidades de blocos if em seu código.

Para instalar o pacote Assertion, você deve executar o seguinte comando:

1
composer require beberlei/assert

Por exemplo, se quiser verificar o endereço de e-mail de um usuário, você pode fazer assim:

1
2
3
4
5
6
7
8
9
use Assert\Assertion;
use Assert\AssertionFailedException;
//...
try {
    Assertion::email($value, "The value must be valid E-mail address");
} catch(AssertionFailedException $e) {
    $e->getValue(); // the value that caused the failure
    $e->getConstraints(); // the additional constraints of the assertion.
}
 

***************************

O que são exceções?

Em geral, uma exceção é quando, durante o processamento de uma ação dentro do código, foge do esperado e requer um processamento especial. Dentro do PHP é possível usar o conceito de try… catch… finally.

<?php
try {
  // code here
}
catch (Exception $e) {
  // code for expcetion
}
finally {
  // code to run either if successfull or failure
}

Por que utilizar exceções customizadas?

Ok, mas por que não utilizar a exception padrão da linguagem? Os motivos são bastante simples:

  • Fácil entendimento do erro: uma exceção deve mostrar de forma rápida e simples o motivo e origem do problema;
  • Adicionar informações relevantes: a fim de facilitar o debug, principalmente por outros desenvolvedores, no momento de realizar a correção;
  • Exceções genéricas não apontam o caminho a ser seguido: no momento do tratamento de uma exceção, trabalhar com exceções genéricas requerem a interpretação de um programador. Utilizando uma exceção não genérica, muitos dos problemas (inclusive mensagens de erro para o usuário final) podem se manipulados de forma mais eficiente.

Criando exceções no Laravel

Como tudo no Laravel, o artisan está aí para isso! O código abaixo ira gerar uma nova exceção dentro da pasta app/exceptions do seu projeto:

$ php artisan make:exception MyNewException
<?php

namespace App\Exceptions;

use Exception;

class MyNewExcpetion extends Exception
{

}

Por boas práticas, mantemos sempre o Exception no final do nome de nossa exceção. Isso facilitará para futuros desenvolvedores entenderem que o que ele está recebendo é de fato uma exceção.

O código gerado anteriormente, por si só, já estaria completo e poderiamos utilizar nossa exception e teriamos, caso o debug esteja ativado, o seguinte retorno:

App \ Exceptions \ MyNewException
My error message

Customizando minha exceção

Como todas as exceções são tratadadas, quando não tratadas, pela classe App\Exceptions\Handler do Laravel, podemos ir além! A classe utiliza duas ótimas funções para que o programador possa customizar ainda mais o comportamente da exceção:

  • report: permite customizar o envio da exceção para um gerenciador de erros (como Sentry, Bugsnag, etc);
  • render: exibe a exceção como uma resposta HTTP (ótimo para exceções que precisam ser mostradas de forma amigável para o usuário).

Podemos aplicar da seguinte forma dentro de nossa exceção criada anteriormente:

<?php

namespace App\Exceptions;

use Exception;

class MyNewExcpetion extends Exception
{
    /**
     * Report the exception.
     *
     * @return void
     */
    public function report()
    {
        //
    }

    /**
     * Render the exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request
     * @return \Illuminate\Http\Response
     */
    public function render($request)
    {
        return response(...);
    }
}

Veja também que é possível chegar no mesmo objetivo de forma genérica direto dentro da classe App\Exceptions\Handler alterando as funções ali presentes.

Ainda dentro do Handler do Laravel é possível customizar dois pontos:

  • Exceções que não devem ser reportadas: basta adicionar as classes dentro da variavel $dontReport;
  • Inputs que não devem persistir com o flash: que precisam ser adicionadas na variável $dontFlash.

Reportando uma exceção e continuando a execução

Em alguns casos, ao receber uma exceção, desejamos seguir algum outro caminho. Porém, pode ser interessante fazer o log dessa exceção para futura análise, sem prejudicar o funcionamento da plataforma.

Para isso, a framework disponibiliza um helper: report($exception)

Basta enviar a exceção para a função que ela executará o report da classe Handler.

Exceções HTTP

Para finalizar, o Laravel já vem com algumas páginas de erro HTTP padrão. Erros como 404 (páginas não encontrada) e 500 (erro interno do servidor) são apresentados para o usuário como uma página HTML:

Página 404 do Laravel 5.7

Para customizar as páginas de erro, basta criar dentro de 
resources/views/errors/ as páginas blade. Lembre-se que as páginas devem ser nomeadas de acordo com o status HTTP que deseja exibir. Ou seja, para uma página de erro 404, o arquivo deverá ser nomeado 404.blade.php.

Caso queira apenas dar uma mudada no padrão do Laravel, a framework permite publicar as páginas pré-existentes com o seguinte comando:

php artisan vendor:publish --tag=laravel-errors

As views serão adicionadas ao caminho das páginas de erro.

 
 

 

 


2

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (15) Variados (109) PHP (130) Laravel (157) Black Hat (3) front-end (28) linux (113) postgresql (39) Docker (26) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (54) devops (25) nodejs (5) npm (2) nvm (1) git (8) firefox (1) react (6) reactnative (5) collections (1) javascript (6) reactjs (7) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (1) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (11) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (4) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (1) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (40) Kubernetes (2) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (1) jwt (4) security (2) translate (1) kube (1) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (2) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (2) Architecture (3) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (1) autorizacao (2) authentication (4) authorization (2) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1)

New Articles



Get Latest Updates by Email