Spaces:
No application file
No application file
| namespace Mautic\CoreBundle\Controller; | |
| use Mautic\ApiBundle\Helper\RequestHelper; | |
| use Mautic\CoreBundle\Helper\ThemeHelper; | |
| use Symfony\Component\ErrorHandler\Exception\FlattenException; | |
| use Symfony\Component\HttpFoundation\JsonResponse; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpFoundation\Response; | |
| use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; | |
| class ExceptionController extends CommonController | |
| { | |
| public function showAction(Request $request, \Throwable $exception, ThemeHelper $themeHelper, DebugLoggerInterface $logger = null) | |
| { | |
| $exception = FlattenException::createFromThrowable($exception, $exception->getCode(), $request->headers->all()); | |
| $class = $exception->getClass(); | |
| $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1)); | |
| $layout = 'prod' == MAUTIC_ENV ? 'Error' : 'Exception'; | |
| $code = $exception->getStatusCode(); | |
| // All valid status codes are within the range of 100 to 599, inclusive | |
| // @see https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes | |
| if ($code < 100 || $code > 599) { | |
| // thrown exception that didn't set a code | |
| $code = 500; | |
| } | |
| // Special handling for oauth and api urls | |
| if ( | |
| (str_contains($request->getUri(), '/oauth') && !str_contains($request->getUri(), 'authorize')) | |
| || RequestHelper::isApiRequest($request) | |
| || (!defined('MAUTIC_AJAX_VIEW') && str_contains($request->server->get('HTTP_ACCEPT', ''), 'application/json')) | |
| ) { | |
| $allowRealMessage = | |
| 'dev' === MAUTIC_ENV | |
| || str_contains($class, 'UnexpectedValueException') | |
| || str_contains($class, 'NotFoundHttpException') | |
| || str_contains($class, 'AccessDeniedHttpException'); | |
| $message = $allowRealMessage | |
| ? $exception->getMessage() | |
| : $this->translator->trans( | |
| 'mautic.core.error.generic', | |
| ['%code%' => $code] | |
| ); | |
| $dataArray = [ | |
| 'errors' => [ | |
| [ | |
| 'message' => $message, | |
| 'code' => $code, | |
| 'type' => null, | |
| ], | |
| ], | |
| ]; | |
| if ('dev' == MAUTIC_ENV) { | |
| $dataArray['trace'] = $exception->getTrace(); | |
| } | |
| // Normal behavior in Symfony dev mode is to send 200 with error message, | |
| // but this is used in prod mode for all "/api" requests too. (#224) | |
| return new JsonResponse($dataArray, $code); | |
| } | |
| if ($request->get('prod')) { | |
| $layout = 'Error'; | |
| } | |
| $anonymous = $this->security->isAnonymous(); | |
| $baseTemplate = '@MauticCore/Default/slim.html.twig'; | |
| if ($anonymous) { | |
| if ($templatePage = $themeHelper->getTheme()->getErrorPageTemplate((string) $code)) { | |
| $baseTemplate = $templatePage; | |
| } | |
| } | |
| $template = "@MauticCore/{$layout}/{$code}.html.twig"; | |
| if (!$this->get('twig')->getLoader()->exists($template)) { | |
| $template = "@MauticCore/{$layout}/base.html.twig"; | |
| } | |
| $statusText = Response::$statusTexts[$code] ?? ''; | |
| $url = $request->getRequestUri(); | |
| $urlParts = parse_url($url); | |
| return $this->delegateView( | |
| [ | |
| 'viewParameters' => [ | |
| 'baseTemplate' => $baseTemplate, | |
| 'status_code' => $code, | |
| 'status_text' => $statusText, | |
| 'exception' => $exception, | |
| 'logger' => $logger, | |
| 'currentContent' => $currentContent, | |
| 'isPublicPage' => $anonymous, | |
| ], | |
| 'contentTemplate' => $template, | |
| 'passthroughVars' => [ | |
| 'error' => [ | |
| 'code' => $code, | |
| 'text' => $statusText, | |
| 'exception' => ('dev' == MAUTIC_ENV) ? $exception->getMessage() : '', | |
| 'trace' => ('dev' == MAUTIC_ENV) ? $exception->getTrace() : '', | |
| ], | |
| 'route' => $urlParts['path'], | |
| ], | |
| 'responseCode' => $code, | |
| ] | |
| ); | |
| } | |
| /** | |
| * @param int $startObLevel | |
| */ | |
| protected function getAndCleanOutputBuffering($startObLevel): string|false | |
| { | |
| if (ob_get_level() <= $startObLevel) { | |
| return ''; | |
| } | |
| Response::closeOutputBuffers($startObLevel + 1, true); | |
| return ob_get_clean(); | |
| } | |
| } | |