I've been thinking a bit more about the problem discussed under 461c803
I believe the class inheritance is not the real problem for configuring checked/unchecked exceptions. All the exceptions can be arranged in tree graph, and you can unambiguously decide whether a given class is checked or unchecked - the original implementation using checkedExceptions and ignoredExceptions handled this correctly.
Let's take a look at the "problematic" case you mentioned:
when ho have @throws LogicException as unchecked, it could throws SomeMyCheckedLogicException and you have a problem - analysis will process it as unchecked.
- Current configuration options (even after removal of possibility to combine whitelist/blacklist) allow you to get into the exact same situation - simply use:
checkedExceptions: [SomeMyCheckedLogicException]
- In your own code you should never have
@throws LogicException. All @throws annotations with unchecked exception class should be reported as an error.
- For too generic
@throws annotations in 3rd party code, you can either use methodThrowTypeDeclarations parameter in phpstan config, or you can catch and rewrap/rethrow specific exceptions in your code.
The real problem comes from interfaces - any class can implement multiple interfaces, and even worse any interface may inherit from multiple interfaces. Even with a pretty strict rules that you suggested in 461c803 it's still really easy to construct an exception with ambiguous resolution of checked/unchecked, e.g.
interface CheckedFoo {}
interface UncheckedFoo extends CheckedFoo {}
interface CheckedBar {}
class AmICheckedOrUncheckedException extends Exception implements UncheckedFoo, CheckedBar {}
checkedExceptions: [CheckedFoo, CheckedBar]
uncheckedExceptions: [UncheckedFoo]
I'm not really sure how to solve this. Maybe the checkedExceptions and uncheckedExceptions parameters should always contain only class names, but not interfaces?
I've been thinking a bit more about the problem discussed under 461c803
I believe the class inheritance is not the real problem for configuring checked/unchecked exceptions. All the exceptions can be arranged in tree graph, and you can unambiguously decide whether a given class is checked or unchecked - the original implementation using checkedExceptions and ignoredExceptions handled this correctly.
Let's take a look at the "problematic" case you mentioned:
checkedExceptions: [SomeMyCheckedLogicException]@throws LogicException. All@throwsannotations with unchecked exception class should be reported as an error.@throwsannotations in 3rd party code, you can either usemethodThrowTypeDeclarationsparameter in phpstan config, or you can catch and rewrap/rethrow specific exceptions in your code.The real problem comes from interfaces - any class can implement multiple interfaces, and even worse any interface may inherit from multiple interfaces. Even with a pretty strict rules that you suggested in 461c803 it's still really easy to construct an exception with ambiguous resolution of checked/unchecked, e.g.
I'm not really sure how to solve this. Maybe the
checkedExceptionsanduncheckedExceptionsparameters should always contain only class names, but not interfaces?