Laravel 5.5 - 仅记录 500 错误,从不通过 api 发送错误详细信息?

Laravel 5.5 - Only log 500 error, never send error details via api?

我制作了以下控制器来演示处理 api 时遇到的 500 个错误的问题。我希望能够检测到何时会抛出 500 错误,这样它就永远不会到达客户端(因为与客户端共享的细节太多,它们应该只由 Laravel 记录)。

方法getUser() return由于错字 firsgt()

故意造成 500 错误
class TestController extends Controller {
  public function getUser() {
    $data = User::firsgt(); //returns 500 error
    return $data;
  }
}

这是客户看到的:

我们如何 return 像 'Error occurred' 这样的错误消息而不是为客户提供太多详细信息 'Call to undefined method App\User::firsgt()'?

注意:我不想为每个控制器方法一一处理,而是在 returned 到客户端之前捕获任何 500,并且 return 自定义 500 通用留言'Error occurred'

您有 app/Exception/Handler.php class 的时间来执行此操作。例如,您可以使用类似这样的代码:

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();
}

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

显然,如果您正在设计 API,可能根本没有必要使用 parent::render(),您应该以自定义方式处理自定义异常 classes,最后再处理其他异常例外情况只是 return 500 次响应,包含您想要的消息。

您可以使用try ... catch

try{
   .....
}catch(\Exception $e){
  if($e->getCode() == 500){
      return response()->json(["error"=>'$e->getCode()'],500);
  }
}

Laravel 已经为您完成了此操作,但前提是您处于生产模式并且请求预期 JSON.

总之,App\Exceptions\Handlerclass是可以处理所有异常的地方。它也是 Laravel 本身记录和呈现所有异常的地方。

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

    return parent::render($request, $exception);
}

只需更改 .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

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

APP_DEBUG=true

改为:

APP_DEBUG=false

这将仅显示标准错误响应。查看有关 error details.

的文档

如果要使用来自 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
                });