0

我制作了下面的控制器来演示处理我在使用 api 时遇到的 500 个错误的问题。我希望能够检测到何时会抛出 500 错误,因此它永远不会发送给客户端(因为与客户端共享的细节太多,它们只能由 Laravel 记录)。

由于拼写错误,该方法getUser()故意返回 500 错误firsgt()

class TestController extends Controller {
  public function getUser() {
    $data = User::firsgt(); //returns 500 error
    return $data;
  }
}

这是客户看到的: 在此处输入图像描述

我们如何才能返回类似“发生错误”的错误消息,而不是返回客户端“调用未定义方法 App\User::firsgt()”的太多详细信息?

注意:我不想为每个控制器方法一个一个地处理它,而是在返回给客户端之前捕获任何 500,并返回自定义的 500 通用消息“发生错误”

4

6 回答 6

2

你有app/Exception/Handler.php课来做这件事。例如,您可以使用与此类似的代码:

public function render($request, Exception $e)
{
    $exception_class = get_class($e);

    if (!in_array($exception_class, [ValidationException::class, ModelNotFoundException::class] ) {
       return response()->json(['info' => 'Error occurred'], 500);
    }

   return parent::render();
}

但是正如您所看到的,您应该排除一些您希望以正常方式呈现的异常类,这里只是一些示例异常类。

显然,如果您正在设计 API,可能根本没有必要使用parent::render(),您应该以自定义方式处理自定义异常类,然后最后对于其他异常,只需返回 500 响应以及您想要的消息。

于 2017-11-15T17:10:46.897 回答
2

只需更改.env文件中的变量以防止这些消息与响应一起发送。

APP_ENV=生产

APP_DEBUG=false

编辑:只需设置APP_DEBUG为 false 就足够了。

更新: 如果您使用的是 dingo api 包,那么除了设置APP_DEBUG为 false 之外,您还需要编辑配置文件。

如果您还没有完成,请发布 dingo 配置文件

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

然后,打开 config/api.php 并将errorFormat值编辑为您想要的任何消息。

替换:message为通用消息

于 2017-11-15T17:14:07.750 回答
1

您可以使用try ... catch

try{
   .....
}catch(\Exception $e){
  if($e->getCode() == 500){
      return response()->json(["error"=>'$e->getCode()'],500);
  }
}
于 2017-11-15T17:11:47.597 回答
1

Laravel 已经为您完成了这项工作,但前提是您处于生产模式并且请求需要 JSON。

总之,App\Exceptions\Handler类是可以处理所有异常的地方。它也是 Laravel 自己记录和渲染所有异常的地方。

public function render($request, Exception $exception)
{
    // your logic here

    return parent::render($request, $exception);
}
于 2017-11-15T17:12:44.650 回答
1

错误的详细解释显示在开发环境中,对于生产,您不想显示它们-出于安全原因-因此,正如@Hamoud 所述,转到您的.ENV文件找到该行:

APP_DEBUG=true

将其更改为:

APP_DEBUG=false

这将仅显示标准错误响应。检查有关错误详细信息的文档。

于 2017-11-15T17:37:23.303 回答
0

如果您想使用来自 Laravel 响应的消息数据,自然地,您需要查找包含消息的响应数据。这仅在 APP_DEBUG=true 时有效,这不应该在生产中启用,但为了清楚起见:

假设您正在使用axios发出请求,它看起来像这样:

axios.get("/api/catalogs/clients/")
                .then(res => {
                    this.client = res.data;
                })
                .catch(e => {
                    print(e.message); //This would print Server error
                    this.clientError = e.response.data.message; //This will print Call to undefined method
                });
于 2021-08-19T19:17:28.983 回答