【问题标题】:PHP: Prevent nested try-catch from catching a specific errorPHP:防止嵌套的try-catch捕获特定错误
【发布时间】:2016-12-28 20:55:44
【问题描述】:

我有一个 PHP 脚本,它需要执行回调函数并捕获特定类型的错误。

<?php

class MyException extends Exception{}

function doStuff(callable $callback){

    try{
        $callback();
    }
    catch(MyException $e){
        #Deal with it
    }
}

?>

回调函数可以使用 try-catch 来防止我的异常冒泡。如何允许回调函数实现 try-catch 块但不允许它捕获 MyException?

【问题讨论】:

  • 我不认为你可以。
  • 用例?我看不出不允许回调处理自己的异常背后的原因,这个回调本来是第一个抛出异常的回调。
  • @Devon 我怀疑用例是回调使用他的库,并且库抛出异常。
  • 我唯一能想到的就是不要让它成为Exception 的子类。那么如果他的代码有catch(Exception $e),它就不会捕获它。
  • @Barmar 没错。我希望回调不知道错误的含义。我只想回调停止并返回库,以便它可以处理问题。

标签: php try-catch


【解决方案1】:

如果我读错了问题,请原谅我 - 我想不出需要这样做的用例 - 但我认为这样的事情会起作用:

<?php

class MyException extends Exception {}

/*
 * This method is in the library. It's not in your control
 */
function doStuff(callable $callback) {
    try {
        $callback();
    } catch(Exception $e) {
        die($e->getMessage());
    }
}

/*
 * We want to do something, but not let any MyException pass through to doStuff()
 */
doStuff(function() {
    try {
        connect('mysql:dbname=IDoNotExist;host=127.0.0.1', 'batman', 'robin');
    } catch(MyException $e) {
        return; // Do nothing with MyException, continue as if it didn't happen
    } catch(Exception $e) {
        throw new Exception($e); // Not an instance of MyException ... let the library handle it
    }
});

/*
 * This is dummy code that will throw MyException if the username and password are incorrect
 */
function connect($dsn, $username, $password) {
    try {
        $dbh = new PDO($dsn, $username, $password);
    } catch(PDOException $e) {
        throw new MyException($e->getMessage());
    }
}

通过阅读 cmets 和您的回复,我假设 doStuff() 是您将 callable 传递给的某个库调用。如果您的回调中的代码捕获到MyException,您希望完全忽略它。

上面的代码将完全忽略MyException,就好像什么都没发生一样。虽然我绝不会提倡这样的解决方案。

【讨论】:

  • 我确实希望 MyException 被 doStuff() 函数中的 try-catch 拾取。我试图防止该特定异常被回调中的任何代码捕获,以确保它始终冒泡。本质上我不希望回调覆盖我的错误处理。
  • 从每个人的 cmets 看来,我需要重新考虑整个工作方式。在回调中使用 try-catch 并返回 true/false 以显示回调是否成功可能会更好。谢谢大家的帮助。我会再考虑一下,希望能提出一个更合适的解决方案。
猜你喜欢
  • 2018-04-18
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
相关资源
最近更新 更多