Tratamento de Exceções

Configuração

config/exception.php

return [
    // Aqui configure a classe de tratamento de exceções
    '' => support\exception\Handler::class,
];

No modo de múltiplas aplicações, você pode configurar uma classe de tratamento de exceções separadamente para cada aplicação, consulte Múltiplas Aplicações.

Classe de Tratamento de Exceções Padrão

No webman, as exceções são tratadas por padrão pela classe support\exception\Handler. É possível modificar o arquivo de configuração config/exception.php para alterar a classe de tratamento de exceções padrão. A classe de tratamento de exceções deve implementar a interface Webman\Exception\ExceptionHandlerInterface.

interface ExceptionHandlerInterface
{
    /**
     * Registra logs
     * @param Throwable $e
     * @return mixed
     */
    public function report(Throwable $e);

    /**
     * Renderiza a resposta
     * @param Request $request
     * @param Throwable $e
     * @return Response
     */
    public function render(Request $request, Throwable $e) : Response;
}

Renderização da Resposta

O método render na classe de tratamento de exceções é usado para renderizar a resposta.

Se o valor debug no arquivo de configuração config/app.php for true (daqui em diante app.debug=true), retornará informações detalhadas da exceção; caso contrário, retornará informações resumidas da exceção.

Se a requisição esperar um retorno em json, as informações da exceção serão retornadas em formato json, semelhante a

{
    "code": "500",
    "msg": "Informação da exceção"
}

Se app.debug=true, os dados json incluirão um campo adicional trace com a pilha de chamadas detalhada.

Você pode escrever sua própria classe de tratamento de exceções para alterar a lógica de tratamento de exceções padrão.

Exceção de Negócio BusinessException

Às vezes, queremos interromper a requisição em uma função aninhada e retornar uma mensagem de erro para o cliente, e isso pode ser feito lançando uma BusinessException.
Por exemplo:

<?php
namespace app\controller;

use support\Request;
use support\exception\BusinessException;

class FooController
{
    public function index(Request $request)
    {
        $this->chackInpout($request->post());
        return response('hello index');
    }

    protected function chackInpout($input)
    {
        if (!isset($input['token'])) {
            throw new BusinessException('Erro nos parâmetros', 3000);
        }
    }
}

O exemplo acima retornará um

{"code": 3000, "msg": "Erro nos parâmetros"}

Nota
A exceção de negócio BusinessException não precisa ser capturada com try, o framework irá capturá-la automaticamente e retornar a saída apropriada com base no tipo de requisição.

Exceção de Negócio Personalizada

Se a resposta acima não atender às suas necessidades, como querer mudar msg para message, você pode personalizar uma MyBusinessException.

Crie app/exception/MyBusinessException.php com o seguinte conteúdo

<?php

namespace app\exception;

use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;

class MyBusinessException extends BusinessException
{
    public function render(Request $request): ?Response
    {
        // Retorna dados json para requisições json
        if ($request->expectsJson()) {
            return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
        }
        // Para requisições não json, retorna uma página
        return new Response(200, [], $this->getMessage());
    }
}

Assim, quando o negócio chamar

use app\exception\MyBusinessException;

throw new MyBusinessException('Erro nos parâmetros', 3000);

Uma requisição json receberá um retorno json semelhante a

{"code": 3000, "message": "Erro nos parâmetros"}

Dica
Como as exceções BusinessException pertencem a erros de negócio (como erros nos parâmetros de entrada do usuário), elas são previsíveis, portanto o framework não as considera erros fatais e não registra logs.

Resumo

Sempre que você quiser interromper a requisição atual e retornar informações ao cliente, considere usar a exceção BusinessException.