PHP (or other): Strategy to deal with exceptions that “cannot occur”

随声附和 提交于 2020-06-28 10:56:06

问题


Consider the following code.

class C {}

/**
 * @throws \InvalidArgumentException
 */
function classCreateInstance($class) {
  if (!is_string($class)) {
    throw new \InvalidArgumentException("Class name must be a string.");
  }
  if (!class_exists($class)) {
    throw new \InvalidArgumentException("Class '$class' does not exist.");
  }
  return new $class();
}

/**
 * @return C
 */
function foo() {
  return classCreateInstance(C::class);
}

There is one function that may throw an exception, because it does not know anything about the $class argument.

On the other hand, the calling code knows that 'C' is a valid class name, so it would like to assume that the "InvalidArgumentException" will never occur. It would like to avoid verbose try/catch, and it would like to avoid having its own @throws tag. Especially if it is not "allowed" to have one, because it is implementing an interface that does not annotate the exception.

But, from an IDE / automatic code validation perspective, ignoring this exception is not safe.

So.. what is the correct way to deal with exceptions that are "almost impossible" from a calling code perspective?


回答1:


In Java. there is a distinction between "checked" exception classes and "unchecked" exception classes. Only the checked exceptions are part of the interface contract, whereas throwing an "unchecked" exception is allowed even if the interface does not declare it.

In Java, in the "should never occur" case, one would throw an unchecked exception - e.g. a "RuntimeException".

In PHP, this is all convention-based. Methods can throw whichever exceptions they want. Adding a @throws tag in the doc comment is nice, but it is not enforced by the language.

However, an IDE, or possibly other code reviewing tools, can be configured to analyse code based on the Java model of checked vs unchecked exceptions.

E.g. PhpStorm has options to not require a @throws doc tag for RuntimeException and LogicException. So this would allow to treat these as "unchecked", but then write custom exception classes and treat them like "checked" exceptions in Java.

Native exception classes in PHP: http://php.net/manual/en/spl.exceptions.php#spl.exceptions.tree Not that these all inherit from LogicException or RuntimeException, so they would all be considered as "unchecked". Only the root class, Exception (and custom child classes) would be considered as "checked".

This distinction also means that if you call a method/function with no declared/annotated exception, you still need to consider that an exception could be thrown nevertheless. This could be covered e.g. by a try/catch at the top level of the application. (e.g. an index.php)



来源:https://stackoverflow.com/questions/35586882/php-or-other-strategy-to-deal-with-exceptions-that-cannot-occur

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!