Handler.php中的render函数不工作Laravel 8



ModelNotFoundException发生时,我希望返回JSON响应,而不是默认的404错误页面。为此,我在appExceptionsHandler.php:中编写了以下代码

public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
return response()->json([
'error' => 'Resource not found'
], 404);
}
return parent::render($request, $exception);
}

但是它不起作用。当ModelNotFoundException发生时,Laravel只显示一个空白页面。我发现,即使在Handler.php中声明一个空的渲染函数,Laravel也会在ModelNotFoundException上显示一个空白页面。

如何修复此问题,使其能够返回JSON/执行overriden呈现函数内的逻辑?

在Laravel 8x中,您需要在register()方法中使用Rendering Exceptions

use AppExceptionsCustomException;
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->renderable(function (CustomException $e, $request) {
return response()->view('errors.custom', [], 500);
});
}

对于ModelNotFoundException,您可以按以下方式进行操作。

use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
public function register()
{
$this->renderable(function (NotFoundHttpException $e, $request) {
return response()->json(...);
});
}

默认情况下,Laravel异常处理程序会将异常转换为HTTP响应。但是,您可以为给定类型的异常注册自定义呈现闭包。您可以通过异常处理程序的renderable方法来实现这一点。Laravel将通过检查闭包的类型提示来推断闭包呈现的异常类型:

有关错误异常的更多信息

此代码不适用于我(在Laravel 8.74.0中(:

$this->renderable(function (ModelNotFoundException$e, $request) {
return response()->json(...);
});

不知道为什么,但ModelNotFoundException被直接转发到Laravel使用的NotFoundHttpException(它是Symfony组件的一部分(,并最终触发404 HTTP响应。我的解决方法是检查异常的getPrevious()方法:

$this->renderable(function (NotFoundHttpException $e, $request) {
if ($request->is('api/*')) {
if ($e->getPrevious() instanceof ModelNotFoundException) {
return response()->json([
'status' => 204,
'message' => 'Data not found'
], 200);
}
return response()->json([
'status' => 404,
'message' => 'Target not found'
], 404);
}
});

然后我们就会知道这个异常来自ModelNotFoundException,并用NotFoundHttpException返回不同的响应。

编辑

这就是ModelNotFoundException作为NotFoundHttpException抛出的原因

这是我的处理程序文件:

use Throwable;
public function render($request, Throwable $exception)
{
if( $request->is('api/*')){
if ($exception instanceof ModelNotFoundException) {
$model = strtolower(class_basename($exception->getModel()));

return response()->json([
'error' => 'Model not found'
], 404);
}
if ($exception instanceof NotFoundHttpException) {
return response()->json([
'error' => 'Resource not found'
], 404);

}
}
}

这只适用于API路由中的所有请求。如果您想捕获所有请求,请删除第一个If.

请注意,默认情况下,Laravel仅在发送带有标头参数Accept: application/json的请求时才会发出异常的JSON表示!对于所有其他请求,Laravel发送正常的HTML渲染输出。

相关内容

  • 没有找到相关文章

最新更新