Slim3 / DRY - 如何在不重复代码的情况下正确处理错误/异常?

时间:2016-12-08 13:58:01

标签: php slim slim-3

我正在使用Slim3处理相当大的JSON API。我的控制器/操作目前乱七八糟:

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

在应用程序的某些点上,任何事情都可能出错并且响应需要适当。但有一点很常见,即错误响应总是相同的。 status始终为errordata是可选的(如果表单验证错误data将包含这些),message设置为指示API的用户或消费者出了什么问题。

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

从我的头脑中,我能想到的就是创建一个自定义异常,例如App\Exceptions\AppException,其中选项datamessage将从{{1}获得}}

$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; } } 包装在try / catch中的中间件:

$next

现在我在代码中的所有点都要$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' ]); } });

我唯一的问题是感觉我错误地使用了异常,这可能会让调试变得更加困难。

有关减少重复项和清除错误响应的任何建议吗?

1 个答案:

答案 0 :(得分:3)

您可以通过创建输出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示例实施。