configuration = $configuration; } /** * Handles exceptions thrown during rendering of content objects * The handler can decide whether to re-throw the exception or * return a nice error message for production context. * * @param array $contentObjectConfiguration * @throws \Exception */ public function handle(\Exception $exception, ?AbstractContentObject $contentObject = null, $contentObjectConfiguration = []): string { // ImmediateResponseException (and the derived PropagateResponseException) should work similar to // exit / die and must therefore not be handled by this ExceptionHandler. if ($exception instanceof ImmediateResponseException) { throw $exception; } if (!empty($this->configuration['ignoreCodes.']) && in_array($exception->getCode(), array_map('intval', $this->configuration['ignoreCodes.']), true) ) { throw $exception; } $errorMessage = $this->configuration['errorMessage'] ?? 'Oops, an error occurred! Request: {requestId}'; // $code and it's placeholder %s for b/w compatibility $code = $this->context->getAspect('date')->getDateTime()->format('YmdHis') . $this->random->generateRandomHexString(8); $errorMessage = str_replace('%s', '{code}', $errorMessage); // Log exception except HMAC validation exceptions caused by potentially forged requests if (!in_array($exception->getCode(), AbstractExceptionHandler::IGNORED_HMAC_EXCEPTION_CODES, true)) { $this->logger->alert($errorMessage, ['exception' => $exception, 'code' => $code, 'requestId' => $this->requestId]); } // Return interpolated error message return str_replace(['{code}', '{requestId}'], [$code, (string)$this->requestId], $errorMessage); } }