| Conditions | 13 |
| Paths | 51 |
| Total Lines | 99 |
| Code Lines | 36 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 3 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 41 | public static function exception( |
||
| 42 | string $exceptionClass, |
||
| 43 | string $message = '', |
||
| 44 | int $code = 0, |
||
| 45 | ?\Throwable $previous = null, |
||
| 46 | array $arguments = [] |
||
| 47 | ): \Throwable { |
||
| 48 | // Check if $class is empty |
||
| 49 | if (empty($exceptionClass)) { |
||
| 50 | throw new Exceptions\ExceptionNameIsEmpty(); |
||
| 51 | } |
||
| 52 | |||
| 53 | $params = [&$message, $code, $previous]; |
||
| 54 | |||
| 55 | // Check if exceptionClass with that name already exists |
||
| 56 | // we mute class_exists because we leave second parameter as a default (which is true by default) |
||
| 57 | // in order to autoload the class if exists, but if we do not mute it and the class does not exists |
||
| 58 | // then aside from returned boolean false, we get some php warnings like this: |
||
| 59 | // Warning: include(/path/to/MyCustomException.php): failed to open stream: No such file or directory |
||
| 60 | // That is normal behaviour since we ask to autoload a class which does not exists yet. |
||
| 61 | // On the second run when we request the class that has been generated, it will be autoload here |
||
| 62 | if (!@\class_exists($exceptionClass)) { |
||
| 63 | // Check if is namespace |
||
| 64 | if (false !== \strpos($exceptionClass, '\\')) { |
||
| 65 | throw new Exceptions\NamespaceError(); |
||
| 66 | } |
||
| 67 | |||
| 68 | // Check if the class already exists |
||
| 69 | if (!self::fileSystem()->has(self::makeFileName($exceptionClass))) { |
||
| 70 | // Default class to extend from |
||
| 71 | $extendFromClass = \Exception::class; |
||
| 72 | |||
| 73 | if (self::isEventStreamEnabled()) { |
||
| 74 | // Since EventStream is enabled then we extend from BaseError Abstract |
||
| 75 | $extendFromClass = Abstracts\FaultManagerException::class; // @codeCoverageIgnore |
||
| 76 | } |
||
| 77 | |||
| 78 | // Persist generated exceptionClass into file under compiled directory |
||
| 79 | self::persistFile( |
||
| 80 | $exceptionClass, |
||
| 81 | self::generateFileCode($exceptionClass, $extendFromClass) |
||
| 82 | ); |
||
| 83 | } |
||
| 84 | |||
| 85 | if (self::autoloadEnabled()) { |
||
| 86 | // Load custom generated class |
||
| 87 | self::loadCustomException(self::fileSystem()->compiledExceptions([$exceptionClass])->current()); |
||
| 88 | } else { |
||
| 89 | $reflection = self::reflectFromFile(self::compilePath() . self::makeFileName($exceptionClass)); |
||
| 90 | } |
||
| 91 | } |
||
| 92 | |||
| 93 | $reflection = $reflection ?? self::reflectFromClassName($exceptionClass); |
||
| 94 | |||
| 95 | |||
| 96 | // Get exceptionClass interfaces |
||
| 97 | // The reason we do not get an instance here and use instanceof is because if we get an instance here |
||
| 98 | // then the event will be triggered and also: |
||
| 99 | // PHP gets the line on which the object was instantiated [http://php.net/manual/en/throwable.getline.php] |
||
| 100 | $interfaces = $reflection->getInterfaceNames(); |
||
| 101 | |||
| 102 | // Make sure that the requested class is \Throwable |
||
| 103 | if (!\in_array(\Throwable::class, $interfaces, true)) { |
||
| 104 | throw new Exceptions\BaseError( |
||
| 105 | 'The class "%s" does not implements Throwable interface.', |
||
| 106 | null, |
||
| 107 | null, |
||
| 108 | [$exceptionClass] |
||
| 109 | ); |
||
| 110 | } |
||
| 111 | |||
| 112 | // Check if exceptionClass implements BaseError interface or if is a Hoa\Exception |
||
| 113 | if (\in_array(Interfaces\FaultManagerException::class, $interfaces, true) || |
||
| 114 | \in_array('Hoa\Exception', $interfaces, true) |
||
| 115 | ) { |
||
| 116 | // Then we pass $arguments as fourth parameter for constructor |
||
| 117 | $params[] = $arguments; |
||
| 118 | } elseif (0 < \count($arguments)) { |
||
| 119 | // if there are arguments set then format the exception message |
||
| 120 | $message = @vsprintf($message, $arguments); |
||
| 121 | } |
||
| 122 | |||
| 123 | // Get exception instance |
||
| 124 | //TODO: Use native Reflection untill this is solved: https://github.com/Roave/BetterReflection/pull/375 |
||
| 125 | /** @var \Throwable $exception */ |
||
| 126 | $exception = (new \ReflectionClass($exceptionClass))->newInstanceArgs($params); |
||
| 127 | |||
| 128 | if (!($exception instanceof \Hoa\Event\Source) && |
||
| 129 | self::isEventStreamEnabled() |
||
| 130 | ) { |
||
| 131 | // Mutate the object |
||
| 132 | self::mutate($exception); |
||
| 133 | // Route exceptions that are either PHP build-in or are already predefined and do not |
||
| 134 | // have support for FaultManager EventStream |
||
| 135 | //TODO: maybe make RouteExceptions plugin to follow Singleton Pattern? |
||
| 136 | self::registerEvent(new Plugins\RouteExceptions(), $exception); |
||
| 137 | } |
||
| 138 | |||
| 139 | return $exception; |
||
| 140 | } |
||
| 155 |