簡體   English   中英

Slim3 / DRY - 如何在不重復代碼的情況下正確處理錯誤/異常?

[英]Slim3/DRY - How to handle errors/exceptions correctly without duplicating code?

我正在使用Slim3處理一個相當大的JSON API。 我的控制器/操作目前亂七八糟,具體如下:

return $response->withJson([
    'status' => 'error',
    'data' => null,
    'message' => 'Username or password was incorrect'
]);

在應用程序的某些點上,任何事情都可能出錯並且響應需要適當。 但有一點很常見,即錯誤響應總是相同的。 status始終為errordata是可選的(在表單驗證錯誤的情況下, data將包含這些data )並且設置message以向API的用戶或消費者指示出錯的地方。

我聞到代碼重復。 如何減少代碼重復?

從我的頭腦中我所能想到的就是創建一個自定義異常,例如App\\Exceptions\\AppException ,它接受選項datamessage將從$e->getMessage()

<?php

namespace App\Exceptions;

class AppException extends Exception
{
    private $data;

    public function __construct($message, $data = null, $code = 0, $previous = null)
    {
        $this->data = $data;
        parent::__construct($message, $code, $previous);
    }

    public function getData()
    {
        return $this->data;
    }
}

然后創建調用$next包含在try / catch中的中間件:

$app->add(function($request, $response, $next) {

  try {
    return $next($request, $response);
  }
  catch(\App\Exceptions\AppException $e)
  {
    $container->Logger->addCritical('Application Error: ' . $e->getMessage());
    return $response->withJson([
      'status' => 'error',
      'data' => $e->getData(),
      'message' => $e->getMessage()
    ]);
  }
  catch(\Exception $e)
  {
    $container->Logger->addCritical('Unhandled Exception: ' . $e->getMessage());
    $container->SMSService->send(getenv('ADMIN_MOBILE'), "Shit has hit the fan! Run to your computer and check the error logs. Beep. Boop.");
    return $response->withJson([
      'status' => 'error',
      'data' => null,
      'message' => 'It is not possible to perform this action right now'
    ]);
  }
});

現在,我在代碼中所要做的就是throw new \\App\\Exceptions\\AppException("Username or password incorrect", null)

我唯一的問題是感覺我出於錯誤的原因使用異常,這可能會使調試變得更加困難。

有關減少重復和清理錯誤響應的任何建議嗎?

您可以通過創建輸出JSON的錯誤處理程序來實現類似的類似結果。

namespace Slim\Handlers;

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

final class ApiError extends \Slim\Handlers\Error
{
    public function __invoke(Request $request, Response $response, \Exception $exception)
    {
        $status = $exception->getCode() ?: 500;
        $data = [
            "status" => "error",
            "message" => $exception->getMessage(),
        ];
        $body = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
        return $response
                   ->withStatus($status)
                   ->withHeader("Content-type", "application/json")
                   ->write($body);
    }
}

您還必須配置Slim以使用自定義錯誤處理程序。

$container = $app->getContainer();

$container["errorHandler"] = function ($container) {
    return new Slim\Handlers\ApiError;
};

檢查Slim API Skeleton以獲取示例實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM