【问题标题】:How to return a Slim response from a subfunction call?如何从子函数调用返回 Slim 响应?
【发布时间】:2019-10-01 08:48:18
【问题描述】:

这个控制器(通过__invoke函数调用)调用另一个函数来处理一些数据,我想从第二个函数processData返回一个错误响应,可以吗?

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args)
{
    $someData = ...;
    $processedData = $this->processData($someData, $response);
    return $response->withJson($processedData);
}

private function processData(ResponseInterface $response)
{
    ...
    $error = true; // simulate error
    if($error){
        return $response->withJson('error', 500);
    } else {
        return $processedData;
    }
}

从子函数调用返回错误响应不起作用,因为响应必须从主函数返回。

我怎样才能做到这一点?

一种解决方案是从子函数中抛出错误,但我想返回适当的苗条响应。

【问题讨论】:

  • $processedData(从processData()返回)也是ResponseInterface类型吗?
  • processData() 应该返回修改后的数据,而不是 ResponseInterface,尽管我希望能够在必要时在 processData() 中抛出 Slim 错误响应。希望它足够清楚。

标签: slim


【解决方案1】:

据我了解,processData() 在发生任何错误时返回响应对象,否则返回另一种类型的数据。这意味着这个方法在不同的情况下返回两种不同类型的数据,所以在你的控制器中你需要以不同的方式处理它的返回值:如果它返回一个响应对象,你可以按原样返回它,但如果它返回处理后的数据,您需要返回使用该数据构建的 json 响应......这让事情有点混乱。

您关于抛出错误的想法似乎很好,并且您应该知道您可以(并且必须)在出现任何错误时返回正确的响应。这就是 Slim 错误处理程序应该返回响应对象的原因。

要重构您的代码,我看到了以下选项:

  1. processData() 中抛出异常并定义一些自定义异常类并编写良好的错误处理程序以产生正确的错误响应(推荐
private function processData(ResponseInterface $response)
{
    ...
    $error = true; // simulate error
    if($error){
        throw new DataProcessingException('Details about why this happened');
    }
    return $processedData;
}
// in your controller

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args)
{
    $someData = ...;
    $processedData = $this->processData($someData, $response);
    return $response->withJson($processedData);
}

// in error handler

...
catch (\DataProcessingException $e) {
    return $response->withJson(['error' => 'A data processing exception has occurred', 'details' => $e->getMessage()], 500);
}
  1. 在出现任何错误时在processData() 中抛出异常并在控制器中处理:
private function processData(ResponseInterface $response)
{
    ...
    $error = true; // simulate error
    if($error){
        throw new \Exception('error message');
    }
    return $processedData;
}

// in your controller

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args)
{
    $someData = ...;
    try {
        $processedData = $this->processData($someData, $response);
        return $response->withJson($processedData);
    }
    catch (\Exception $e) {
        return $response->withJson('error', 500);
    }
}
  1. processData()中,返回$processedData或某个值(例如FALSE)表示错误,并在控制器中生成相应的响应(不推荐):
private function processData(ResponseInterface $response)
{
    ...
    $error = true; // simulate error
    if($error){
        return false;
    }
    return $processedData;
}
// in your controller

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args)
{
    $someData = ...;
    $processedData = $this->processData($someData, $response);
    if ($processedData === false) {
        return $response->withJson('error', 500);
    }
    return $response->withJson($processedData);

}

【讨论】:

  • 能否请您添加一些有关错误处理程序的信息。我不确定如何正确设置它。
  • 您使用的是哪个版本的 Slim?
  • 我使用的是 slim 3,
  • 您是否尝试编写自己的错误处理程序?看看这里slimframework.com/docs/v3/handlers/error.html 了解如何,请注意,您的自定义错误处理程序会收到一个$exception,您可以检查它以不同方式处理不同类型的异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2022-01-19
相关资源
最近更新 更多