Slim3/Dry-如何正确处理错误/异常而不复制代码



我正在使用Slim3处理相当大的JSON API。我的控制器/操作目前乱扔以下内容:

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

在应用程序中的某些方面,任何事情都可能出错,并且响应需要适当。但是常见的一件事是错误响应始终是相同的。status始终是errordata是可选的(在形式验证错误的情况下,data将包含这些错误),并且将message设置为向API的用户或消费者指示。

我闻到代码重复的味道。如何减少代码重复?

从我的头顶上,我能想到的就是创建一个自定义异常,诸如AppExceptionsAppException采用选项data,并且message将获得$e->getMessage()

<?php
namespace AppExceptions;
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包裹在试用/捕获中:

$app->add(function($request, $response, $next) {
  try {
    return $next($request, $response);
  }
  catch(AppExceptionsAppException $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 AppExceptionsAppException("Username or password incorrect", null)

我唯一的问题是,出于错误的原因,感觉就像我在使用例外,这可能会使调试变得更加困难。

关于减少重复项并清理错误响应的任何建议?

您可以通过创建一个输出JSON的错误处理程序来获得相似的结果。

namespace SlimHandlers;
use PsrHttpMessageServerRequestInterface as Request;
use PsrHttpMessageResponseInterface as Response;
final class ApiError extends SlimHandlersError
{
    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 SlimHandlersApiError;
};

检查Slim API骨架,例如实现。

最新更新