【问题标题】:Laravel 5.5 - Only log 500 error, never send error details via api?Laravel 5.5 - 仅记录 500 错误,从不通过 api 发送错误详细信息?
【发布时间】:2018-04-29 00:22:10
【问题描述】:

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

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

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

这是客户看到的:

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

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

【问题讨论】:

    标签: laravel laravel-5 api-design laravel-5.5 laravel-response


    【解决方案1】:

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

    【讨论】:

      【解决方案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 替换为通用消息

      【讨论】:

      • 这在标准 laravel 上效果很好,但我在使用 dingo api 时遇到了问题。标记为正确,因为它可以帮助其他人和我自己解决 laravel 解决方案(我认为这可以解决我的具体问题),但在与 dingo api 一起使用时不起作用。将为同一问题的 dingo api 版本打开一个问题。
      【解决方案3】:

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

      APP_DEBUG=true
      

      改成:

      APP_DEBUG=false
      

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

      【讨论】:

        【解决方案4】:

        您有 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 响应以及您想要的消息。

        【讨论】:

        • 谢谢你,我为 laravel 找到了,只做APP_DEBUG = false 要容易得多,所以它可以安全地处理错误/通常为客户“发生错误”。我的问题仍然存在,但与 dingo api 相关,所以我打开了同样的问题,但针对 dingo api。
        【解决方案5】:

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

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

        public function render($request, Exception $exception)
        {
            // your logic here
        
            return parent::render($request, $exception);
        }
        

        【讨论】:

          【解决方案6】:

          您可以使用try ... catch

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

          【讨论】:

          • true,但我不想在我的代码中为所有控制器方法显式使用 try catch。只是一种简单的全局方法来处理任何 500 次 laravel 抛出并捕获冒泡的错误。
          猜你喜欢
          • 2011-05-25
          • 1970-01-01
          • 2016-11-27
          • 1970-01-01
          • 1970-01-01
          • 2018-04-03
          • 2019-05-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多