@@ -67,7 +67,7 @@ |
||
| 67 | 67 | $this->setLongDescription( |
| 68 | 68 | "Use this command to see what Storyplayer will use as the default " |
| 69 | 69 | ."environment to test against." |
| 70 | - .PHP_EOL.PHP_EOL |
|
| 70 | + .PHP_EOL . PHP_EOL |
|
| 71 | 71 | ."This command mostly exists to assist tab-completion scripts for UNIX shells." |
| 72 | 72 | ); |
| 73 | 73 | } |
@@ -59,87 +59,87 @@ |
||
| 59 | 59 | */ |
| 60 | 60 | class StaticConfigManager extends ConfigManagerBase |
| 61 | 61 | { |
| 62 | - const USER_DOTFILE = 'storyplayer.json'; |
|
| 62 | + const USER_DOTFILE = 'storyplayer.json'; |
|
| 63 | 63 | |
| 64 | - /** |
|
| 65 | - * load the default config file |
|
| 66 | - * |
|
| 67 | - * @param StaticConfig $config |
|
| 68 | - * @return void |
|
| 69 | - */ |
|
| 70 | - public function loadDefaultConfig($config, $defaultConfigFilename) |
|
| 71 | - { |
|
| 72 | - // load the default config file |
|
| 73 | - $this->configHelper->loadConfigFile($config, $defaultConfigFilename); |
|
| 74 | - } |
|
| 64 | + /** |
|
| 65 | + * load the default config file |
|
| 66 | + * |
|
| 67 | + * @param StaticConfig $config |
|
| 68 | + * @return void |
|
| 69 | + */ |
|
| 70 | + public function loadDefaultConfig($config, $defaultConfigFilename) |
|
| 71 | + { |
|
| 72 | + // load the default config file |
|
| 73 | + $this->configHelper->loadConfigFile($config, $defaultConfigFilename); |
|
| 74 | + } |
|
| 75 | 75 | |
| 76 | - /** |
|
| 77 | - * @param StaticConfig $config |
|
| 78 | - * @return void |
|
| 79 | - */ |
|
| 80 | - public function loadUserConfig($config) |
|
| 81 | - { |
|
| 82 | - try { |
|
| 83 | - // We start with an empty config |
|
| 84 | - $this->configHelper->loadDotFileConfig($config, self::APP_NAME, self::USER_DOTFILE); |
|
| 85 | - } |
|
| 86 | - catch (E4xx_ConfigFileNotFound $e) { |
|
| 87 | - // we don't care - user configs are optional |
|
| 88 | - } |
|
| 89 | - // all done |
|
| 90 | - } |
|
| 76 | + /** |
|
| 77 | + * @param StaticConfig $config |
|
| 78 | + * @return void |
|
| 79 | + */ |
|
| 80 | + public function loadUserConfig($config) |
|
| 81 | + { |
|
| 82 | + try { |
|
| 83 | + // We start with an empty config |
|
| 84 | + $this->configHelper->loadDotFileConfig($config, self::APP_NAME, self::USER_DOTFILE); |
|
| 85 | + } |
|
| 86 | + catch (E4xx_ConfigFileNotFound $e) { |
|
| 87 | + // we don't care - user configs are optional |
|
| 88 | + } |
|
| 89 | + // all done |
|
| 90 | + } |
|
| 91 | 91 | |
| 92 | - /** |
|
| 93 | - * |
|
| 94 | - * @return array<string> |
|
| 95 | - */ |
|
| 96 | - public function getListOfConfigFiles($dirs) |
|
| 97 | - { |
|
| 98 | - // do we have a credible search list? |
|
| 99 | - if (!is_array($dirs)) { |
|
| 100 | - // fraid not |
|
| 101 | - return []; |
|
| 102 | - } |
|
| 92 | + /** |
|
| 93 | + * |
|
| 94 | + * @return array<string> |
|
| 95 | + */ |
|
| 96 | + public function getListOfConfigFiles($dirs) |
|
| 97 | + { |
|
| 98 | + // do we have a credible search list? |
|
| 99 | + if (!is_array($dirs)) { |
|
| 100 | + // fraid not |
|
| 101 | + return []; |
|
| 102 | + } |
|
| 103 | 103 | |
| 104 | - $return = []; |
|
| 105 | - foreach ($dirs as $dirToSearch) |
|
| 106 | - { |
|
| 107 | - // find JSON config files |
|
| 108 | - $files = $this->configHelper->getListOfConfigFilesIn($dirToSearch, 'json'); |
|
| 109 | - foreach ($files as $filename) { |
|
| 110 | - $return[basename($filename, '.json')] = $filename; |
|
| 111 | - } |
|
| 112 | - } |
|
| 104 | + $return = []; |
|
| 105 | + foreach ($dirs as $dirToSearch) |
|
| 106 | + { |
|
| 107 | + // find JSON config files |
|
| 108 | + $files = $this->configHelper->getListOfConfigFilesIn($dirToSearch, 'json'); |
|
| 109 | + foreach ($files as $filename) { |
|
| 110 | + $return[basename($filename, '.json')] = $filename; |
|
| 111 | + } |
|
| 112 | + } |
|
| 113 | 113 | |
| 114 | - // all done |
|
| 115 | - return $return; |
|
| 116 | - } |
|
| 114 | + // all done |
|
| 115 | + return $return; |
|
| 116 | + } |
|
| 117 | 117 | |
| 118 | - public function loadConfigFilesFrom($dirs) |
|
| 119 | - { |
|
| 120 | - // our list of loaded config files |
|
| 121 | - $return = []; |
|
| 118 | + public function loadConfigFilesFrom($dirs) |
|
| 119 | + { |
|
| 120 | + // our list of loaded config files |
|
| 121 | + $return = []; |
|
| 122 | 122 | |
| 123 | - // the files to load |
|
| 124 | - $filenames = $this->getListOfConfigFiles($dirs); |
|
| 123 | + // the files to load |
|
| 124 | + $filenames = $this->getListOfConfigFiles($dirs); |
|
| 125 | 125 | |
| 126 | - // load the files |
|
| 127 | - foreach ($filenames as $filename) |
|
| 128 | - { |
|
| 129 | - $config = new BaseObject(); |
|
| 130 | - $this->configHelper->loadConfigFile($config, $filename); |
|
| 131 | - $return[basename($filename, '.json')] = $config; |
|
| 132 | - } |
|
| 126 | + // load the files |
|
| 127 | + foreach ($filenames as $filename) |
|
| 128 | + { |
|
| 129 | + $config = new BaseObject(); |
|
| 130 | + $this->configHelper->loadConfigFile($config, $filename); |
|
| 131 | + $return[basename($filename, '.json')] = $config; |
|
| 132 | + } |
|
| 133 | 133 | |
| 134 | - // all done |
|
| 135 | - return $return; |
|
| 136 | - } |
|
| 134 | + // all done |
|
| 135 | + return $return; |
|
| 136 | + } |
|
| 137 | 137 | |
| 138 | - public function loadConfigFile($filename) |
|
| 139 | - { |
|
| 140 | - $config = new BaseObject(); |
|
| 141 | - $this->configHelper->loadConfigFile($config, $filename); |
|
| 138 | + public function loadConfigFile($filename) |
|
| 139 | + { |
|
| 140 | + $config = new BaseObject(); |
|
| 141 | + $this->configHelper->loadConfigFile($config, $filename); |
|
| 142 | 142 | |
| 143 | - return $config; |
|
| 144 | - } |
|
| 143 | + return $config; |
|
| 144 | + } |
|
| 145 | 145 | } |
@@ -102,8 +102,7 @@ discard block |
||
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | $return = []; |
| 105 | - foreach ($dirs as $dirToSearch) |
|
| 106 | - { |
|
| 105 | + foreach ($dirs as $dirToSearch) { |
|
| 107 | 106 | // find JSON config files |
| 108 | 107 | $files = $this->configHelper->getListOfConfigFilesIn($dirToSearch, 'json'); |
| 109 | 108 | foreach ($files as $filename) { |
@@ -124,8 +123,7 @@ discard block |
||
| 124 | 123 | $filenames = $this->getListOfConfigFiles($dirs); |
| 125 | 124 | |
| 126 | 125 | // load the files |
| 127 | - foreach ($filenames as $filename) |
|
| 128 | - { |
|
| 126 | + foreach ($filenames as $filename) { |
|
| 129 | 127 | $config = new BaseObject(); |
| 130 | 128 | $this->configHelper->loadConfigFile($config, $filename); |
| 131 | 129 | $return[basename($filename, '.json')] = $config; |
@@ -72,9 +72,9 @@ discard block |
||
| 72 | 72 | |
| 73 | 73 | // how we will talk with the command |
| 74 | 74 | $pipesSpec = [ |
| 75 | - [ 'file', 'php://stdin', 'r' ], |
|
| 76 | - [ 'pipe', 'w' ], |
|
| 77 | - [ 'pipe', 'w' ] |
|
| 75 | + ['file', 'php://stdin', 'r'], |
|
| 76 | + ['pipe', 'w'], |
|
| 77 | + ['pipe', 'w'] |
|
| 78 | 78 | ]; |
| 79 | 79 | $pipes = []; |
| 80 | 80 | |
@@ -110,7 +110,7 @@ discard block |
||
| 110 | 110 | // timeout has happened |
| 111 | 111 | // |
| 112 | 112 | // this makes sure that we do not burn CPU for the sake of it |
| 113 | - $readable = [ $pipes[1], $pipes[2] ]; |
|
| 113 | + $readable = [$pipes[1], $pipes[2]]; |
|
| 114 | 114 | $writeable = $except = []; |
| 115 | 115 | stream_select($readable, $writeable, $except, 1); |
| 116 | 116 | |
@@ -104,8 +104,7 @@ |
||
| 104 | 104 | // |
| 105 | 105 | // best thing to do is to keep reading from our pipes until |
| 106 | 106 | // the pipes no longer exist |
| 107 | - while (!feof($pipes[1]) || !feof($pipes[2])) |
|
| 108 | - { |
|
| 107 | + while (!feof($pipes[1]) || !feof($pipes[2])) { |
|
| 109 | 108 | // block until there is something to read, or until the |
| 110 | 109 | // timeout has happened |
| 111 | 110 | // |
@@ -152,8 +152,8 @@ discard block |
||
| 152 | 152 | // build the full command |
| 153 | 153 | // |
| 154 | 154 | $fullCommand = 'cp ' |
| 155 | - . "'" . $sourceFilename . "' " |
|
| 156 | - . "'" . $destFilename . "'"; |
|
| 155 | + . "'" . $sourceFilename . "' " |
|
| 156 | + . "'" . $destFilename . "'"; |
|
| 157 | 157 | |
| 158 | 158 | // run the command |
| 159 | 159 | $commandRunner = $this->st->getNewCommandRunner(); |
@@ -182,8 +182,8 @@ discard block |
||
| 182 | 182 | // build the full command |
| 183 | 183 | // |
| 184 | 184 | $fullCommand = 'cp ' |
| 185 | - . "'" . $sourceFilename . "' " |
|
| 186 | - . "'" . $destFilename . "'"; |
|
| 185 | + . "'" . $sourceFilename . "' " |
|
| 186 | + . "'" . $destFilename . "'"; |
|
| 187 | 187 | |
| 188 | 188 | // run the command |
| 189 | 189 | $commandRunner = $this->st->getNewCommandRunner(); |
@@ -158,7 +158,7 @@ discard block |
||
| 158 | 158 | { |
| 159 | 159 | return [ |
| 160 | 160 | '-o StrictHostKeyChecking=no', // avoid prompting for accepting |
| 161 | - // a host key |
|
| 161 | + // a host key |
|
| 162 | 162 | ]; |
| 163 | 163 | } |
| 164 | 164 | |
@@ -166,9 +166,9 @@ discard block |
||
| 166 | 166 | { |
| 167 | 167 | return [ |
| 168 | 168 | '-o StrictHostKeyChecking=no', // avoid prompting for accepting |
| 169 | - // a host key |
|
| 169 | + // a host key |
|
| 170 | 170 | '-n' // attach stdin to /dev/null - req to run SSH when not |
| 171 | - // connected to a terminal |
|
| 171 | + // connected to a terminal |
|
| 172 | 172 | ]; |
| 173 | 173 | } |
| 174 | 174 | |
@@ -384,10 +384,10 @@ discard block |
||
| 384 | 384 | // the command to run on the remote/guest OS |
| 385 | 385 | // (assumes the command will be globbed by the remote shell) |
| 386 | 386 | $fullCommand = 'ssh ' |
| 387 | - . ' ' . $this->getSshKeyForUse() |
|
| 388 | - . ' ' . $this->getSshOptionsForUse() |
|
| 389 | - . ' ' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 390 | - . ' "' . str_replace('"', '\"', $command) . '"'; |
|
| 387 | + . ' ' . $this->getSshKeyForUse() |
|
| 388 | + . ' ' . $this->getSshOptionsForUse() |
|
| 389 | + . ' ' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 390 | + . ' "' . str_replace('"', '\"', $command) . '"'; |
|
| 391 | 391 | |
| 392 | 392 | // run the command |
| 393 | 393 | //$log->startStep("run command via SSH: {$fullCommand}"); |
@@ -435,11 +435,11 @@ discard block |
||
| 435 | 435 | // <additional SSH options> |
| 436 | 436 | // any other flags, such as -n to force non-interactive session |
| 437 | 437 | $fullCommand = 'scp ' |
| 438 | - . ' ' . $this->getSshKeyForUse() |
|
| 439 | - . ' ' . $this->getScpOptionsForUse() |
|
| 440 | - . ' "' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 441 | - . ':' . $sourceFilename . '"' |
|
| 442 | - . ' "' . $destFilename . '"'; |
|
| 438 | + . ' ' . $this->getSshKeyForUse() |
|
| 439 | + . ' ' . $this->getScpOptionsForUse() |
|
| 440 | + . ' "' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 441 | + . ':' . $sourceFilename . '"' |
|
| 442 | + . ' "' . $destFilename . '"'; |
|
| 443 | 443 | |
| 444 | 444 | // run the command |
| 445 | 445 | $commandRunner = $this->st->getNewCommandRunner(); |
@@ -486,11 +486,11 @@ discard block |
||
| 486 | 486 | // <additional SSH options> |
| 487 | 487 | // any other flags, such as -n to force non-interactive session |
| 488 | 488 | $fullCommand = 'scp ' |
| 489 | - . ' ' . $this->getSshKeyForUse() |
|
| 490 | - . ' ' . $this->getScpOptionsForUse() |
|
| 491 | - . ' "' . $sourceFilename . '" ' |
|
| 492 | - . ' "' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 493 | - . ':' . $destFilename . '"'; |
|
| 489 | + . ' ' . $this->getSshKeyForUse() |
|
| 490 | + . ' ' . $this->getScpOptionsForUse() |
|
| 491 | + . ' "' . $sourceFilename . '" ' |
|
| 492 | + . ' "' . $this->getSshUsername() . '@' . $this->getIpAddress() |
|
| 493 | + . ':' . $destFilename . '"'; |
|
| 494 | 494 | |
| 495 | 495 | // run the command |
| 496 | 496 | $commandRunner = $this->st->getNewCommandRunner(); |
@@ -356,8 +356,7 @@ |
||
| 356 | 356 | { |
| 357 | 357 | $list = $hardCodedDefaults->getConfigs(); |
| 358 | 358 | |
| 359 | - foreach ($list as $name => $config) |
|
| 360 | - { |
|
| 359 | + foreach ($list as $name => $config) { |
|
| 361 | 360 | $this->addEntry($name, $config); |
| 362 | 361 | } |
| 363 | 362 | } |
@@ -90,6 +90,9 @@ discard block |
||
| 90 | 90 | |
| 91 | 91 | /** |
| 92 | 92 | * constructor |
| 93 | + * @param string $configType |
|
| 94 | + * @param string[] $searchFolders |
|
| 95 | + * @param ConfigFinder[] $configFinders |
|
| 93 | 96 | */ |
| 94 | 97 | public function __construct($configType, $searchFolders, $configFinders) |
| 95 | 98 | { |
@@ -186,6 +189,7 @@ discard block |
||
| 186 | 189 | /** |
| 187 | 190 | * load a SPv2.0-style JSON configs |
| 188 | 191 | * |
| 192 | + * @param string $filename |
|
| 189 | 193 | * @return object |
| 190 | 194 | */ |
| 191 | 195 | protected function loadJsonConfig($filename) |
@@ -204,7 +208,8 @@ discard block |
||
| 204 | 208 | * @todo we need (at some point) to move the check for a return value |
| 205 | 209 | * out to somewhere else |
| 206 | 210 | * |
| 207 | - * @return object |
|
| 211 | + * @param string $filename |
|
| 212 | + * @return TestEnvironment_Definition |
|
| 208 | 213 | */ |
| 209 | 214 | protected function loadPhpConfig($filename) |
| 210 | 215 | { |
@@ -360,7 +365,7 @@ discard block |
||
| 360 | 365 | /** |
| 361 | 366 | * returns our list of all known configs |
| 362 | 367 | * |
| 363 | - * @return array |
|
| 368 | + * @return SystemUnderTestConfig[] |
|
| 364 | 369 | */ |
| 365 | 370 | public function getEntries() |
| 366 | 371 | { |
@@ -370,7 +375,7 @@ discard block |
||
| 370 | 375 | /** |
| 371 | 376 | * returns the names of all of the entries in our list |
| 372 | 377 | * |
| 373 | - * @return array<string> |
|
| 378 | + * @return integer[] |
|
| 374 | 379 | */ |
| 375 | 380 | public function getEntryNames() |
| 376 | 381 | { |
@@ -55,10 +55,10 @@ discard block |
||
| 55 | 55 | */ |
| 56 | 56 | class HardCodedList |
| 57 | 57 | { |
| 58 | - /** |
|
| 59 | - * our list of configs |
|
| 60 | - * @var array<object> |
|
| 61 | - */ |
|
| 58 | + /** |
|
| 59 | + * our list of configs |
|
| 60 | + * @var array<object> |
|
| 61 | + */ |
|
| 62 | 62 | private $configs = []; |
| 63 | 63 | |
| 64 | 64 | /** |
@@ -76,7 +76,7 @@ discard block |
||
| 76 | 76 | */ |
| 77 | 77 | public function __construct($configType) |
| 78 | 78 | { |
| 79 | - $this->setConfigType($configType); |
|
| 79 | + $this->setConfigType($configType); |
|
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | /** |
@@ -86,7 +86,7 @@ discard block |
||
| 86 | 86 | */ |
| 87 | 87 | public function getConfigType() |
| 88 | 88 | { |
| 89 | - return $this->configType; |
|
| 89 | + return $this->configType; |
|
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | /** |
@@ -99,11 +99,11 @@ discard block |
||
| 99 | 99 | */ |
| 100 | 100 | public function setConfigType($configType) |
| 101 | 101 | { |
| 102 | - if (!class_exists($configType)) { |
|
| 103 | - throw new E4xx_NoSuchConfigClass($configType); |
|
| 104 | - } |
|
| 102 | + if (!class_exists($configType)) { |
|
| 103 | + throw new E4xx_NoSuchConfigClass($configType); |
|
| 104 | + } |
|
| 105 | 105 | |
| 106 | - $this->configType = $configType; |
|
| 106 | + $this->configType = $configType; |
|
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | /** |
@@ -118,15 +118,15 @@ discard block |
||
| 118 | 118 | */ |
| 119 | 119 | public function newConfig($name) |
| 120 | 120 | { |
| 121 | - // create our return object |
|
| 122 | - $classname = $this->configType; |
|
| 123 | - $obj = new $classname(); |
|
| 124 | - $obj->setName($name); |
|
| 121 | + // create our return object |
|
| 122 | + $classname = $this->configType; |
|
| 123 | + $obj = new $classname(); |
|
| 124 | + $obj->setName($name); |
|
| 125 | 125 | |
| 126 | - // add this to the list |
|
| 127 | - $this->addConfig($obj); |
|
| 126 | + // add this to the list |
|
| 127 | + $this->addConfig($obj); |
|
| 128 | 128 | |
| 129 | - return $obj; |
|
| 129 | + return $obj; |
|
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | /** |
@@ -137,13 +137,13 @@ discard block |
||
| 137 | 137 | */ |
| 138 | 138 | public function addConfig($config) |
| 139 | 139 | { |
| 140 | - // make sure the config is compatible first |
|
| 141 | - if (! $config instanceof $this->configType) { |
|
| 142 | - throw new E4xx_IncompatibleConfigClass($this->configType, get_class($config)); |
|
| 143 | - } |
|
| 140 | + // make sure the config is compatible first |
|
| 141 | + if (! $config instanceof $this->configType) { |
|
| 142 | + throw new E4xx_IncompatibleConfigClass($this->configType, get_class($config)); |
|
| 143 | + } |
|
| 144 | 144 | |
| 145 | - // if we get here, then we're good to go |
|
| 146 | - $name = $config->getName(); |
|
| 145 | + // if we get here, then we're good to go |
|
| 146 | + $name = $config->getName(); |
|
| 147 | 147 | $this->configs[$name] = $config; |
| 148 | 148 | |
| 149 | 149 | // keep the list sorted |
@@ -138,7 +138,7 @@ |
||
| 138 | 138 | public function addConfig($config) |
| 139 | 139 | { |
| 140 | 140 | // make sure the config is compatible first |
| 141 | - if (! $config instanceof $this->configType) { |
|
| 141 | + if (!$config instanceof $this->configType) { |
|
| 142 | 142 | throw new E4xx_IncompatibleConfigClass($this->configType, get_class($config)); |
| 143 | 143 | } |
| 144 | 144 | |
@@ -82,7 +82,7 @@ |
||
| 82 | 82 | throw new E4xx_StoryplayerDefaultsSectionMustBeAnArray($this->getFilename()); |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | - foreach($config->defaults as $defaultValue) { |
|
| 85 | + foreach ($config->defaults as $defaultValue) { |
|
| 86 | 86 | if (!is_string($defaultValue)) { |
| 87 | 87 | throw new E4xx_StoryplayerDefaultsMustBeStrings($this->getFilename()); |
| 88 | 88 | } |
@@ -422,8 +422,8 @@ |
||
| 422 | 422 | if ($trace !== null) { |
| 423 | 423 | $this->write(PHP_EOL . "-----" . PHP_EOL, $this->writer->commentStyle); |
| 424 | 424 | $this->write("This is the stack trace for this failure:" |
| 425 | - . PHP_EOL . PHP_EOL |
|
| 426 | - . CodeFormatter::indentBySpaces($trace, 4) . PHP_EOL . PHP_EOL); |
|
| 425 | + . PHP_EOL . PHP_EOL |
|
| 426 | + . CodeFormatter::indentBySpaces($trace, 4) . PHP_EOL . PHP_EOL); |
|
| 427 | 427 | } |
| 428 | 428 | |
| 429 | 429 | // all done |
@@ -92,6 +92,7 @@ |
||
| 92 | 92 | /** |
| 93 | 93 | * called when Storyplayer exits |
| 94 | 94 | * |
| 95 | + * @param boolean $summary |
|
| 95 | 96 | * @return void |
| 96 | 97 | */ |
| 97 | 98 | public function writeFinalReport($duration, $summary) |
@@ -112,11 +112,9 @@ discard block |
||
| 112 | 112 | |
| 113 | 113 | // this is our opportunity to tell the user how our story(ies) |
| 114 | 114 | // went in detail |
| 115 | - foreach ($this->results as $result) |
|
| 116 | - { |
|
| 115 | + foreach ($this->results as $result) { |
|
| 117 | 116 | // so what happened? |
| 118 | - switch ($result->resultCode) |
|
| 119 | - { |
|
| 117 | + switch ($result->resultCode) { |
|
| 120 | 118 | case PhaseGroup_Result::OKAY: |
| 121 | 119 | // this is a good result |
| 122 | 120 | $succeededGroups[] = $result; |
@@ -303,8 +301,7 @@ discard block |
||
| 303 | 301 | |
| 304 | 302 | // does the phase have an exception? |
| 305 | 303 | $e = $phaseResult->getException(); |
| 306 | - if ($e) |
|
| 307 | - { |
|
| 304 | + if ($e) { |
|
| 308 | 305 | $stackTrace = $e->getTrace(); |
| 309 | 306 | $trace = $e->getTraceAsString(); |
| 310 | 307 | } |