不在对象方法内捕获异常

时间:2016-10-16 04:21:45

标签: php exception namespaces

这更适用于文档,因为我已经解决了这个问题,但它很微妙且难以调试,我认为它在公共领域会有用。

问题是我在对象方法中有一个try / catch块,但是没有用。简化示例包含两个文件,如下所示:

TestClass.php:

if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}

Main.php:

<?php
//TestClass.php
namespace MyTest;

class TestClass {
    public function __construct() {
        \e("Initializing object");
        try {
            \e("Trying object exception");
            \throwTestException("Failing gracefully in object");
            \e("After exception");
        } catch (Exception $e) {
            \e($e->getMessage());
        }
        \e("After object init exception");
    }
}
?>

加载Main.php的预期结果如下:

<?php
//Main.php

function e($str) { echo "\n$str"; }
function throwTestException($msg) {
    throw new RuntimeException($msg);
}
require "TestClass.php";

e("Beginning");
try {
    e("First try");
    throwTestException("Failing gracefully first");
    e("After exception");
} catch (Exception $e) {
    e($e->getMessage());
}
e("Ending");

e('');

e('Beginning object test');
new \MyTest\TestClass();
e('Ending object test');
?>

我实际得到的是这样的:

Beginning
First try
Failing gracefully first
Ending

Beginning object test
Initializing object
Trying object exception
Failing gracefully in object
After object init exception
Ending object test

正如您所看到的,异常未被捕获。我尝试了各种各样的事情,只是无法弄清楚为什么它没有被抓住。然后....(见下面的答案)

1 个答案:

答案 0 :(得分:0)

我意识到这是命名空间问题。因为我在名称空间TestClassMyTest中声明了throwTestException,所以我在类方法中对Exception的引用默认为\MyTest\Exception因此不匹配抛出的实际异常,\RuntimeException。因为我实际上并没有尝试从命名空间中实例化异常,所以没有&#34; Unknown Class&#34;出现错误以揭示正在发生的事情。

然后,解决方案就是正确解决我试图捕获的异常类:

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

公平地说,当我构建我的高度减少的例子时,这变得显而易见。它最初并不明显,因为我期望捕获的异常是由类的超类(它是SQLite3类)生成的。因此,在生成异常时我没有必要担心命名空间,而我在捕获它时所考虑的是使用最常见的异常形式Exception。而且,由于我没有实例化该异常 - 仅在catch块中对其进行匹配 - 所以我没有得到任何未解决的通知。