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
});
我制作了以下控制器来演示处理 api 时遇到的 500 个错误的问题。我希望能够检测到何时会抛出 500 错误,这样它就永远不会到达客户端(因为与客户端共享的细节太多,它们应该只由 Laravel 记录)。
方法getUser()
return由于错字 firsgt()
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
});