简体   繁体   English

PHP选择性异常处理

[英]Php selective exception handling

I have a problem where I want to catch all exception except descendants of my custom exception. 我有一个问题要捕获所有异常,但自定义异常的后代除外。

Maybe bad design, but here it is (Simplified and names changed, but the code is quite accurate): 可能是错误的设计,但是这里是(简体字和名称更改,但代码相当准确):

function doStuff()
{
    try {
        // code
        if (something) {
            // manually throw an exception
            throw StuffError("Something is bad.");
        }

        // a third-party code, can throw exceptions
        LibraryClass::arcaneMagic();

    } catch (Exception $e) {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

/** My custom exception */
class StuffError extends Exception
{
    function __construct($msg) {
        parent::__construct('StuffError: ' . $msg);
    }
}

However, the issue here is that I don't want the try-catch to intercept the manually throws StuffError. 但是,这里的问题是我不希望try-catch拦截手动引发的StuffError。 Or, seamlessly rethrow it or something. 或者,无缝地将其扔掉。

As it is now, I'd get: 现在,我会得到:

StuffError: Error occured while doing stuff: StuffError: Something is bad. StuffError:做事务时发生错误:StuffError:不好。

I want just: 我只想:

StuffError: Something is bad. StuffError:不好。

How would I do it? 我该怎么办?

You can have multiple catch clauses, and the first one that matches will be the one that runs. 您可以有多个catch子句,第一个匹配的将是运行的子句。 So you could have something like this: 因此,您可能会遇到这样的事情:

try {
    do_some_stuff();
}
catch (StuffError $e) {
    throw $e;
}
catch (Exception $e) {
    throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}

But you might want to rethink wrapping stuff like this. 但是您可能需要重新考虑包装这样的东西。 It obscures the real cause of the error. 它掩盖了错误的真正原因。 For one thing, you lose the stack trace. 一方面,您会丢失堆栈跟踪。 But it also complicates error handling, since now someone can't differentiate exception types the way you're trying to do, short of trying to parse the exception message (which is rather an anti-pattern in itself). 但这也使错误处理变得复杂,因为现在有人无法像您尝试的那样区分异常类型,而没有尝试解析异常消息(它本身就是反模式)。

I might be misinterpreting you, but I think this is what you're looking for: 我可能会误解您,但我认为这是您要寻找的:

    ...

} catch (Exception $e) {
    if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
        throw $e;
    } else {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

    ...

Replace your catch statement with the code above. 用上面的代码替换您的catch语句。 It checks to see if the exception is a StuffError or a child class of StuffError. 它检查该异常是StuffError还是StuffError的子类。 I'm still very confused at why you would need to throw a StuffError exception after you catch, but maybe that's just some weirdness coming from translating/cleaning your code. 我仍然对为什么在捕获后需要引发StuffError异常感到困惑,但这也许只是翻译/清理代码而产生的怪异之处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM