PHP 中的 Try/Catch 块未捕捉到异常

我试图从这个页面运行示例 # 1: http://php.net/manual/en/language.exceptions.php

<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ',  $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>

However instead of the desired output I get:

0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.'
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7

我使用的开发环境是 UniServer 3.5PHP 5.2.3

90856 次浏览

我最初的想法是你在捕捉/抛出异常的时候有一个输入错误,但是如果你的代码完全一样,我不确定到底发生了什么。

尝试对原始脚本进行以下修改,并粘贴结果。这将有助于更好地诊断你的问题。

<?php


//set up exception handler to report what we didn't catch
function exception_handler($exception) {


if($exception instanceof MyException) {
echo "you didn't catch a myexception instance\n";


} else if($exception instanceof Exception) {
echo "you didn't catch a exception instance\n";


} else {
echo "uncaught exception of type: ".gettype($exception)."\n";
}


echo "Uncaught exception: " , $exception->getMessage(), "\n";
}


//install the handler
set_exception_handler('exception_handler');


class MyException extends Exception {
}


function inverse($x) {
if (!$x) {
throw new MyException('Division by zero.');
}
else return 1/$x;
}


try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (MyException $e) {
echo 'Caught myexception: ',  $e->getMessage(), "\n";
} catch (Exception $e) {
echo 'Caught exception: ',  $e->getMessage(), "\n";
}


// Continue execution
echo 'Hello World';
?>

也许可以尝试禁用您可能已经安装的某些第三方扩展? Http://bugs.php.net/bug.php?id=41744

我在下面的配置中遇到了同样的问题,

PHP 5.2.14(cli)(编译: Aug 12201017:32:30) 版权(c)1997-2010 PHP Group Zend Engine v2.2.0,版权(c)1998-2010年 Zend Technologies 电子加速器 0.9.5.1,版权所有(c)2004-2006电子加速器,由电子加速器

解决方案是要么禁用电子加速器,要么更新它。我两种方法都试过了,两种方法都奏效了。这里报告了这个错误 https://eaccelerator.net/ticket/242(NB。Firefox 抱怨他们的 SSL 证书)。

现在我正在使用以下配置运行 try catch,

PHP 5.2.4 (cli) (built: Oct 16 2007 09:13:35) 版权(c)1997-2007 PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies 与电子加速器 0.9.6.1,版权(c)2004-2010电子加速器,由电子加速器

我只是遇到了这个问题,就好像我已经复制了异常的名称,但是它并没有捕捉到它。事实证明,这是我的愚蠢错误,但我认为我应该把我的情况在这里,以防有其他人在同样的情况。

我在名称空间 A中遇到了异常,脚本在名称空间 B中。问题在于我的 A\MyException等于(在 PHP 中) 我的例外(因为我的脚本在名称空间 B!).我所要做的就是将反斜杠(或者其他名称)添加到异常名称中,这样它看起来就像这样: 一个 MyException

在 PHP 中不能像在 C # (CSharp)这样的其他语言中那样使用典型的 try {} catch {}块。

如果你这样做:

try{
//division by zero
$number = 5/0;
}
catch(Exception $ex){
echo 'Got it!';
}

你不会看到的’得到它!信息从来没有。为什么?这只是因为 PHP 总是需要一个异常来“抛出”。您需要设置自己的错误处理程序,并随之抛出一个 Exception。

参见 Set _ error _ Handler 设置错误处理程序函数: http://php.net/manual/es/function.set-error-handler.php

在 Xdebug,有一种情况:

xdebug.show_exception_trace = 1

这将迫使 php 在 try catch 块中输出异常。 调到 0

这是个老问题了。

I had this problem as well (and that's how I found this post) but just simple experiment allowed me to find the solution. Just try changing Exception to \Exception. Worked for me!

编辑:

正如 sivann 在注释中所指出的,使用名称空间应该做同样的事情。因此,只需将 use \Exception as Exception;放在类声明之前。

尝试把 catch(\Exception $e)代替 catch(Exception $e)。如果您正在使用一个您不太熟悉的代码,或者——特别是——如果您正在使用一个框架,它可能会用自己的代码覆盖默认的 PHP Exception,因此您可能会走错路径并得到不想要的结果。如果您只是放置 \Exception,那么您就可以确保捕获了基本 PHP 异常。

\Exception对我不起作用,但我找到了一个解决方案。

我需要替换:

  try {
...
} catch(Exception $e){
...
}

作者

  try {
...
} catch(Throwable $e){
...
}.

更多信息: https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/

If you are using PHP 7, you may need Throwable instead of Exception

TLDR; 确保在两个 php 文件的顶部都有 use Exception;

我也有这种感觉。我读了 Rowinson Gallego 的评论,该州必须抛出例外。所以我修改了我的代码:

try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw $e;
}

into :

try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw new Exception($e->getMessage(),$e->getCode());
}

有用。

捕获所有异常

 try
{
//place code
throw new Exception('foo');//eg
}
catch (\Throwable $e)
{
dd('for php 7');
} catch (\Exception $e)
{
dd('for php 5');
}

Https://www.php.net/manual/en/language.exceptions.php

在我的情况下,一个奇怪的情况发生,捕捉 Exception不工作,即使我有 \Exception。以下是确保您永远不会错过任何东西并且总是捕捉到错误的方法。

 catch (\Exception $e) {
// do what you want to do on exception catching
} catch (\Throwable $e) {
// do what you want to do on exception catching
}

当你把这两个结合起来,你将永远不会错过一个 Exception。一定要把 \放在 ExceptionThrowable之前。这很重要。

剪辑 抓住他们的有效方法是这样的

catch (\Exception|\Throwable $e) {
// do what you want
}

这将在没有两个单独的 catch 块的情况下捕获它

这条旧线索又重新出现了。

I had not require_once'd the file containing my Exception subclass in the file with the try/catch block.

不知何故(可能是由于作曲家的自动加载) ,这并没有导致“无法解析为类型”错误。而且不知怎么的,我的异常是用预期的名称空间创建的(在另一个文件中,没有 need _ once)。但是没有被抓住。我的目录结构与名称空间不匹配,因此 autoload 可能已经用 try/catch 加载了文件中的正确类,但是在不同的名称空间下。

尝试在类之前添加一个反斜杠,例如:

之前

try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(Magento\Framework\Exception\State\UserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (Magento\Framework\Exception\InvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}

之后

try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(\Magento\Framework\Exception\State\UserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (\Magento\Framework\Exception\InvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}