Operações básicas do projeto ThinkPHP6 (13. Página de erro de resumo de manipulação de exceção personalizada e erro de API em alguns projetos de combate reais)

Prefácio

  Geralmente, o roteamento em um projeto é dividido em retorno 模板引擎页面e retorno api接口json数据. Os dois métodos exigem o retorno de conteúdo diferente. Se a página do mecanismo de modelo encontrar uma exceção, ela precisará retornar uma página de erro. Se a interface api encontrar uma exceção, ela precisará retornar dados json.
  O modo de desenvolvimento e o modo online devem retornar conteúdo diferente. O modo de desenvolvimento deve retornar o máximo possível de informações de erro específicas, enquanto o modo online não pode retornar mensagens de erro específicas. Geralmente, ele exibe um prompt amigável como "Erro do servidor, tente novamente mais tarde". Em vez de exibir um monte de códigos de erro (hostis e inseguros).
  Se houver uma maneira melhor, comentários são bem-vindos.

1. Classificação de anomalias

1. O controlador não pode ser encontrado

Ao acessar a rota, se o controlador estiver errado, você precisa usar a 空控制器interceptação para relatar os erros.

2. Método não encontrado

O método não pode ser encontrado para modificar o controlador BaseController no diretório do aplicativo para substituir o método __call.

3. O recurso solicitado não existe

Para personalizar a interceptação de mensagens de erro, você pode usar o Provedor para personalizar a classe de tratamento de erros, substituir o método de renderização e retornar dados diferentes de acordo com erros diferentes.

4. Exceção interna do sistema, exceção HTTP, etc.

O terceiro ponto.

Dois, tratamento de exceção

1. Pré-processamento

(1) A .envdefinição do arquivo APP_DEBUGdistingue entre o modo de desenvolvimento e o modo online, verdadeiro significa modo de desenvolvimento, falso significa modo online:

APP_DEBUG = true

(2) app/common.phpDefina o apiformato dos dados retornados no arquivo :

function show($status, $message = 'error', $data = [], $httpStatus = 200){
    
    
    $result = [
        "status" => $status,
        "message" => $message,
        "result" => $data
    ];
    return json($result, $httpStatus);
}

(3) Crie um novo provider.php no aplicativo atual e especifique uma classe de tratamento de exceção personalizada:

<?php

// 容器Provider定义文件
return [
    'think\exception\Handle' => 'app\\admin\\exception\\Http',
];

(4) Defina a configuração do código de status, você pode adicionar a configuração do código de status correspondente configna pasta status.php:

<?php

return [
    "success" => 1,
    "error" => 0,

    "http_status" => [
        "not_found" => 404,
        "validate_error" => 422,
        "internal_error" => 500
    ]
];

(5) Prepare as páginas de erro (404, 500, etc.)

2. Código detalhado de manipulação de exceção

(1) O controlador não pode ser encontrado

app/controllerCrie uma nova Errorclasse no diretório ( 文件名固定为Error):

这里需要注意的是,多应用的控制器应该定义在应用文件夹里,这里定义在app目录是为了作用于app下全部应用。

<?php

namespace app\controller;

class Error
{
    
    
    public function __call($name, $arguments)
    {
    
    
        if(request()->isAjax()){
    
    
            return show(config("status.error"), env('app_debug') ? "控制器{
      
      $name}找不到" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));
        }else{
    
    
            return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "控制器{
      
      $name}找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));
        }
    }
}

(2) Método não encontrado

Ao app/BaseController.phpadicionar o __callmétodo do controlador :

public function __call($name, $arguments)
    {
    
    
        if(request()->isAjax()){
    
    
            return show(config("status.error"), env('app_debug') ? "找不到{
      
      $name}方法" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));
        }else{
    
    
            return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "{
      
      $name}方法找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));
        }
    }

(3) O recurso solicitado não existe e o erro do sistema é anormal

app\\admin\\exception\\Http

<?php

namespace app\admin\exception;
use ErrorException;
use Exception;
use InvalidArgumentException;
use ParseError;
use PDOException;
use think\exception\ClassNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\RouteNotFoundException;
use think\Response;
use Throwable;
use TypeError;

class Http extends Handle
{
    
    
    /**
     * Render an exception into an HTTP response.
     *
     * @access public
     * @param \think\Request   $request
     * @param Throwable $e
     * @return Response
     */
    public function render($request, Throwable $e): Response
    {
    
    
        $returnCode = config("status.error");
        $returnMessage = "系统异常,请稍后再试";
        $returnData = [];
        $httpStatus = 500;

        if($e instanceof BusinessException){
    
     // 自定义添加的业务异常
            $returnMessage = $e->getMessage();
            $httpStatus = config("status.http_status.business_error");
        }else if($e instanceof ValidateException){
    
    
            $returnMessage = $e->getError();
            $httpStatus = config("status.http_status.validate_error");
        }else if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {
    
    
            $returnMessage = env('app_debug') ? $e->getMessage() : '当前请求资源不存在,请稍后再试';
            $httpStatus = config("status.http_status.not_found");
        }else if ($e instanceof Exception || $e instanceof PDOException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError || ($e instanceof HttpException && $e->getStatusCode() == 500)) {
    
    
            $returnMessage = env('app_debug') ? $e->getMessage() : '系统异常,请稍后再试';
            $httpStatus = config("status.http_status.internal_error");
        }

        if(request()->isAjax()){
    
    
            return show($returnCode, $returnMessage, $returnData, $httpStatus);
        }else{
    
    
            if($httpStatus == config("status.http_status.not_found")){
    
    
                $errorUrl = 'public/error/admin/404.html';
            }else{
    
    
                $errorUrl = 'public/error/admin/error.html';
            }
            return view(root_path() . $errorUrl, ['e'=>$returnMessage], $httpStatus);
        }

    }
}

A mensagem de erro retornada no código acima eprecisa ser exibida na página de erro (404, erro):

<p class="error-message">{$e ?? ''}</p>

Três, detecção de anomalias

A detecção de anomalia aponta o navegador 页面访问异常e api接口返回异常também precisa verificar 开发模式e 线上模式.

  1. Controlador não existe
  2. Método não existe
  3. Lance ativamente uma exceção
  4. O sistema lança uma exceção

Dicas: apiInterface Você pode usar Postmana simulação de ferramenta, adicione Headers:
Content-Typecomo application/x-www-form-urlencoded
X-Requested-Withestáxmlhttprequest

(Os blogueiros são preguiçosos e não postam capturas de tela, mas eles testaram todos, camaradas experimentem você mesmo, vamos postar um afinal)
Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/zy1281539626/article/details/110847728
Recomendado
Clasificación