|
13 | 13 |
|
14 | 14 | use Symfony\Component\Debug\Exception\FlattenException;
|
15 | 15 | use Symfony\Component\Debug\Exception\OutOfMemoryException;
|
| 16 | +use Symfony\Component\HttpFoundation\Response; |
16 | 17 | use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
|
17 | 18 |
|
18 | 19 | /**
|
@@ -189,6 +190,159 @@ public function sendPhpResponse($exception)
|
189 | 190 | echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
|
190 | 191 | }
|
191 | 192 |
|
| 193 | + /** |
| 194 | + * Gets the content associated with the given exception. |
| 195 | + * |
| 196 | + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance |
| 197 | + * @param string $format The request format (html, json, xml, txt) |
| 198 | + * |
| 199 | + * @return string The formatted content as a string |
| 200 | + */ |
| 201 | + public function getFormattedContent($exception, string $format): string |
| 202 | + { |
| 203 | + switch ($format) { |
| 204 | + case 'json': |
| 205 | + return $this->getJson($exception); |
| 206 | + case 'xml': |
| 207 | + return $this->getXml($exception); |
| 208 | + case 'txt': |
| 209 | + return $this->getTxt($exception); |
| 210 | + default: |
| 211 | + return $this->getHtml($exception); |
| 212 | + } |
| 213 | + } |
| 214 | + |
| 215 | + /** |
| 216 | + * Gets the JSON content associated with the given exception. |
| 217 | + * |
| 218 | + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance |
| 219 | + * |
| 220 | + * @return string The JSON content as a string |
| 221 | + */ |
| 222 | + public function getJson($exception): string |
| 223 | + { |
| 224 | + if (!$exception instanceof FlattenException) { |
| 225 | + $exception = FlattenException::create($exception); |
| 226 | + } |
| 227 | + |
| 228 | + if (404 === $statusCode = $exception->getStatusCode()) { |
| 229 | + $title = 'Not Found'; |
| 230 | + } elseif (class_exists(Response::class) && isset(Response::$statusTexts[$statusCode])) { |
| 231 | + $title = Response::$statusTexts[$statusCode]; |
| 232 | + } else { |
| 233 | + $title = 'Internal Server Error'; |
| 234 | + } |
| 235 | + |
| 236 | + $content = [ |
| 237 | + 'title' => $title, |
| 238 | + 'status' => $statusCode, |
| 239 | + 'detail' => $this->escapeHtml($exception->getMessage()), |
| 240 | + ]; |
| 241 | + |
| 242 | + if ($this->debug) { |
| 243 | + $content['exceptions'] = $exception->toArray(); |
| 244 | + } |
| 245 | + |
| 246 | + return (string) json_encode($content); |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * Gets the XML content associated with the given exception. |
| 251 | + * |
| 252 | + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance |
| 253 | + * |
| 254 | + * @return string The XML content as a string |
| 255 | + */ |
| 256 | + public function getXml($exception): string |
| 257 | + { |
| 258 | + if (!$exception instanceof FlattenException) { |
| 259 | + $exception = FlattenException::create($exception); |
| 260 | + } |
| 261 | + |
| 262 | + if (404 === $statusCode = $exception->getStatusCode()) { |
| 263 | + $title = 'Not Found'; |
| 264 | + } elseif (class_exists(Response::class) && isset(Response::$statusTexts[$statusCode])) { |
| 265 | + $title = Response::$statusTexts[$statusCode]; |
| 266 | + } else { |
| 267 | + $title = 'Internal Server Error'; |
| 268 | + } |
| 269 | + $message = $this->escapeHtml($exception->getMessage()); |
| 270 | + |
| 271 | + $exceptions = ''; |
| 272 | + if ($this->debug) { |
| 273 | + $exceptions .= '<exceptions>'; |
| 274 | + foreach ($exception->toArray() as $e) { |
| 275 | + $exceptions .= sprintf('<exception class="%s" message="%s"><traces>', $e['class'], $this->escapeHtml($e['message'])); |
| 276 | + foreach ($e['trace'] as $trace) { |
| 277 | + $exceptions .= '<trace>'; |
| 278 | + if ($trace['function']) { |
| 279 | + $exceptions .= sprintf('at %s%s%s(%s) ', $trace['class'], $trace['type'], $trace['function'], strip_tags($this->formatArgs($trace['args']))); |
| 280 | + } |
| 281 | + if (isset($trace['file'], $trace['line'])) { |
| 282 | + $exceptions .= strip_tags($this->formatPath($trace['file'], $trace['line'])); |
| 283 | + } |
| 284 | + $exceptions .= '</trace>'; |
| 285 | + } |
| 286 | + $exceptions .= '</traces></exception>'; |
| 287 | + } |
| 288 | + $exceptions .= '</exceptions>'; |
| 289 | + } |
| 290 | + |
| 291 | + return <<<EOF |
| 292 | +<?xml version="1.0" encoding="{$this->charset}" ?> |
| 293 | +<problem xmlns="urn:ietf:rfc:7807"> |
| 294 | + <title>{$title}</title> |
| 295 | + <status>{$statusCode}</status> |
| 296 | + <detail>{$message}</detail> |
| 297 | + {$exceptions} |
| 298 | +</problem> |
| 299 | +EOF; |
| 300 | + } |
| 301 | + |
| 302 | + /** |
| 303 | + * Gets the TXT content associated with the given exception. |
| 304 | + * |
| 305 | + * @param \Exception|FlattenException $exception An \Exception or FlattenException instance |
| 306 | + * |
| 307 | + * @return string The TXT content as a string |
| 308 | + */ |
| 309 | + public function getTxt($exception): string |
| 310 | + { |
| 311 | + if (!$exception instanceof FlattenException) { |
| 312 | + $exception = FlattenException::create($exception); |
| 313 | + } |
| 314 | + |
| 315 | + if (404 === $statusCode = $exception->getStatusCode()) { |
| 316 | + $title = 'Not Found'; |
| 317 | + } elseif (class_exists(Response::class) && isset(Response::$statusTexts[$statusCode])) { |
| 318 | + $title = Response::$statusTexts[$statusCode]; |
| 319 | + } else { |
| 320 | + $title = 'Internal Server Error'; |
| 321 | + } |
| 322 | + |
| 323 | + $content = sprintf("[title] %s\n", $title); |
| 324 | + $content .= sprintf("[status] %s\n", $statusCode); |
| 325 | + $content .= sprintf("[detail] %s\n", $exception->getMessage()); |
| 326 | + |
| 327 | + if ($this->debug) { |
| 328 | + foreach ($exception->toArray() as $i => $e) { |
| 329 | + $content .= sprintf("[%d] %s: %s\n", $i + 1, $e['class'], $e['message']); |
| 330 | + |
| 331 | + foreach ($e['trace'] as $trace) { |
| 332 | + if ($trace['function']) { |
| 333 | + $content .= sprintf('at %s%s%s(%s) ', $trace['class'], $trace['type'], $trace['function'], strip_tags($this->formatArgs($trace['args']))); |
| 334 | + } |
| 335 | + if (isset($trace['file'], $trace['line'])) { |
| 336 | + $content .= strip_tags($this->formatPath($trace['file'], $trace['line'])); |
| 337 | + } |
| 338 | + $content .= "\n"; |
| 339 | + } |
| 340 | + } |
| 341 | + } |
| 342 | + |
| 343 | + return $content; |
| 344 | + } |
| 345 | + |
192 | 346 | /**
|
193 | 347 | * Gets the full HTML content associated with the given exception.
|
194 | 348 | *
|
|
0 commit comments