Php 在Laravel/Lumen中,为什么catch块不捕获我的异常?
在Laravel/Lumen PHP框架中捕获异常的最佳方法是什么?这很可能是一个普遍适用于PHP的问题 目前,我有一个UsersController(在try块中)在我的用户类中调用'findByUsernameOrFail'方法。如果找不到用户名,但catch块未捕获异常,则此方法将引发异常!为什么?Php 在Laravel/Lumen中,为什么catch块不捕获我的异常?,php,laravel,exception-handling,try-catch,lumen,Php,Laravel,Exception Handling,Try Catch,Lumen,在Laravel/Lumen PHP框架中捕获异常的最佳方法是什么?这很可能是一个普遍适用于PHP的问题 目前,我有一个UsersController(在try块中)在我的用户类中调用'findByUsernameOrFail'方法。如果找不到用户名,但catch块未捕获异常,则此方法将引发异常!为什么? class UsersController extends Controller { public function show($username) { tr
class UsersController extends Controller {
public function show($username)
{
try
{
$user = \App\User::findByUsernameOrFail($username);
return $user;
}
catch(Exception $e)
{
// This doesn't work. This code is never called because Laravel
return $this->setStatusCode(404)->respondWithError('Username Not Found!');
}
}
此UsersController中的“show”方法正在调用用户模型中名为“findByUsernameOrFail”的方法。如果它通过用户名找到用户,则返回找到的$User对象。如果它没有通过用户名找到用户,它将抛出一个异常。然而,由于某种原因,这个异常没有被捕获,取而代之的是Laravel正在生成一个通用的错误页面
以下是我的用户模型中的一些代码:
class User extends Illuminate\Database\Eloquent\Model {
public static function findByUsernameOrFail($username)
{
if ( ! is_null($user = static::whereUsername($username)->first()))
{
return $user;
}
throw new Illuminate\Database\Eloquent\ModelNotFoundException;
}
}
下面是我尝试运行此程序时发生的情况的屏幕截图:
为什么我的代码中的“捕获”部分从未执行过!?我想让我的应用程序优雅地返回一个HTTP 404错误,表示找不到用户!根据我对Try/Catch和异常的了解,我的代码应该可以工作,但显然我遗漏了一些东西
如何让此代码按照此代码的预期返回HTTP 404错误消息?我无法用英语解释为什么会发生这种情况。我英语说得很差。只需尝试将
catch(异常$e)
更改为catch(ModelNotFoundException$e)
正如建议的那样,您可能需要明确声明您正在侦听的异常。所以正确的方法是
catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
// do your stuff.
}
但在Laravel中,你可以超越这一点,让它变得非常抽象(就像Laravel中几乎所有的东西一样)
如果在render
方法中打开app/Exceptions/Handler.php
,您可以监听整个应用程序中抛出的各种异常
因此,对于您的特殊情况,可能如下所示:
if ($e instanceof ModelNotFoundException) {
abort(404);
}
(不要忘记导入顶部的完整路径)
正如@phroggy所提到的,您可以利用Laravel的
findOrFail()
方法内联代码。在幕后,它将完全执行您手动执行的操作-尝试查找模型,如果未找到,则抛出异常 使用
捕获(\异常$e)
而不是
catch(Exception$e)虽然没有直接关系,但我会使用
firstOrFail()
而不是显式抛出异常;把它变成一行return static::whereUsername($username)->firstOrFail()
有点晚了,但是您是否使用use Exception在userscocontroller
中导入了异常类代码>在顶部?所有异常都应该从基本异常类扩展,但如果没有正确导入,则类型可能在catch
条件下不匹配。它起作用了。我必须添加一个“\”字符,以使捕获的最终代码看起来像:catch(\lightlight\Database\Eloquent\ModelNotFoundException$e)
catch(\Exception$e)
在Laravel中工作,而catch(Exception$e)
不工作。@endo64是正确的,由于某些名称空间的原因,没有“\”(反斜杠),无法知道原始的正常php异常。