| 1 |  |  | <?php namespace Limoncello\Application\ExceptionHandlers; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * Copyright 2015-2017 [email protected] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  * you may not use this file except in compliance with the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  * You may obtain a copy of the License at | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * http://www.apache.org/licenses/LICENSE-2.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  * Unless required by applicable law or agreed to in writing, software | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  * See the License for the specific language governing permissions and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  * limitations under the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | use Exception; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | use Limoncello\Contracts\Application\ApplicationConfigurationInterface as A; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | use Limoncello\Contracts\Application\CacheSettingsProviderInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | use Limoncello\Contracts\Exceptions\ThrowableHandlerInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | use Limoncello\Contracts\Http\ThrowableResponseInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | use Limoncello\Core\Application\ThrowableResponseTrait; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | use Psr\Container\ContainerExceptionInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | use Psr\Container\ContainerInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | use Psr\Container\NotFoundExceptionInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | use Psr\Log\LoggerInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | use Throwable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | use Whoops\Handler\PlainTextHandler; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | use Whoops\Run; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | use Zend\Diactoros\Response\TextResponse; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  * @package Limoncello\Application | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | class WhoopsThrowableTextHandler implements ThrowableHandlerInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     /** Default HTTP code. */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     protected const DEFAULT_HTTP_ERROR_CODE = 500; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |      * @inheritdoc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |      * @SuppressWarnings(PHPMD.ElseExpression) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 | 3 |  |     public function createResponse(Throwable $throwable, ContainerInterface $container): ThrowableResponseInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 | 3 |  |         $message = 'Internal Server Error'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 | 3 |  |         $this->logException($throwable, $container, $message); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 | 3 |  |         $isDebug = $this->isDebug($container); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 | 3 |  |         if ($isDebug === true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 | 2 |  |             $run = new Run(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |             // If these two options are not used it would work fine with PHP Unit and XDebug, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             // however it produces output to console under PhpDbg. So we need a couple of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             // tweaks to make it work predictably in both environments. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             // | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             // this one forbids Whoops spilling output to console | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 | 2 |  |             $run->writeToOutput(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             // by default after sending error to output Whoops stops execution | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |             // as we want just generated output `string` we instruct not to halt | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 | 2 |  |             $run->allowQuit(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 | 2 |  |             $handler = new PlainTextHandler(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 | 2 |  |             $handler->setException($throwable); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 2 |  |             $run->pushHandler($handler); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 | 2 |  |             $text     = $run->handleException($throwable); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 | 2 |  |             $response = $this->createThrowableTextResponse($throwable, $text, static::DEFAULT_HTTP_ERROR_CODE); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 | 1 |  |             $response = $this->createThrowableTextResponse($throwable, $message, static::DEFAULT_HTTP_ERROR_CODE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 | 3 |  |         return $response; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |      * @param ContainerInterface $container | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |      * @throws ContainerExceptionInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |      * @throws NotFoundExceptionInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 | 3 |  |     private function isDebug(ContainerInterface $container): bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 3 |  |         $appConfig = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         /** @var CacheSettingsProviderInterface $settingsProvider */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 3 |  |         if ($container->has(CacheSettingsProviderInterface::class) === true && | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 3 |  |             ($settingsProvider = $container->get(CacheSettingsProviderInterface::class)) !== null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 | 3 |  |             $appConfig = $settingsProvider->getApplicationConfiguration(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 | 3 |  |         return $appConfig[A::KEY_IS_DEBUG] ?? false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |      * @param Throwable          $exception | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |      * @param ContainerInterface $container | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |      * @param string             $message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |      * @return void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |      * @throws ContainerExceptionInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |      * @throws NotFoundExceptionInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 | 3 |  |     private function logException(Throwable $exception, ContainerInterface $container, string $message): void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 | 3 |  |         if ($container->has(LoggerInterface::class) === true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             /** @var LoggerInterface $logger */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 | 3 |  |             $logger = $container->get(LoggerInterface::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             // The sad truth is that when you have a problem logging might not be available (e.g. no permissions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |             // to write on a disk). We can't do much with it and can only hope that the error information will be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             // delivered to the user other way. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 3 |  |                 $logger->critical($message, ['exception' => $exception]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 | 1 |  |             } catch (Exception $secondException) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |      * @param Throwable $throwable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |      * @param string    $text | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |      * @param int       $status | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |      * @return ThrowableResponseInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |     private function createThrowableTextResponse( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         Throwable $throwable, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         string $text, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         int $status | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |     ): ThrowableResponseInterface { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         return new class ($throwable, $text, $status) extends TextResponse implements ThrowableResponseInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |             use ThrowableResponseTrait; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |             /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |              * @param Throwable $throwable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |              * @param string    $text | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |              * @param int       $status | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 150 |  |  |              */ | 
            
                                                                        
                            
            
                                    
            
            
                | 151 | 3 |  |             public function __construct(Throwable $throwable, string $text, int $status) | 
            
                                                                        
                            
            
                                    
            
            
                | 152 |  |  |             { | 
            
                                                                        
                            
            
                                    
            
            
                | 153 | 3 |  |                 parent::__construct($text, $status); | 
            
                                                                        
                            
            
                                    
            
            
                | 154 | 3 |  |                 $this->setThrowable($throwable); | 
            
                                                                        
                            
            
                                    
            
            
                | 155 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 158 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 159 |  |  |  | 
            
                        
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: