*/ protected static array $blacklist = [ InvalidPrimaryKeyException::class, InvalidArgumentException::class, NotFoundException::class, MethodNotAllowedException::class, NotAcceptableException::class, RecordNotFoundException::class, BadRequestException::class, GoneException::class, ConflictException::class, InvalidCsrfTokenException::class, UnauthorizedException::class, MissingControllerException::class, MissingActionException::class, MissingRouteException::class, MissingViewException::class, MissingTemplateException::class, UnavailableForLegalReasonsException::class, SecurityException::class, AuthSecurityException::class, ]; /** * By design, these exceptions are also 404 with a valid internal referer. * * @var array */ protected static array $evenWithReferer = [ AuthSecurityException::class, ]; /** * @param \Throwable $exception * @param \Psr\Http\Message\ServerRequestInterface|null $request * @return bool */ protected function is404(Throwable $exception, ?ServerRequestInterface $request = null): bool { $blacklist = static::$blacklist; if (isset($this->_config['log404'])) { $blacklist = (array)$this->_config['log404']; } if (!$blacklist) { return false; } $class = get_class($exception); if (!$this->isBlacklisted($class, $blacklist)) { return false; } if (!$request || $this->isBlacklistedEvenWithReferer($class)) { return true; } $referer = $request->getHeaderLine('Referer'); $baseUrl = Configure::read('App.fullBaseUrl'); if (str_starts_with($referer, $baseUrl) && $baseUrl . $request->getRequestTarget() !== $referer) { return false; } return true; } /** * @param string $class * @param array $blacklist * @return bool */ protected function isBlacklisted(string $class, array $blacklist): bool { // Quick string comparison first if (in_array($class, $blacklist, true)) { return true; } // Deep instance of checking foreach ($blacklist as $blacklistedClass) { if ($class instanceof $blacklistedClass) { return true; } } return false; } /** * Is a 404 even with referer present. * * @param string $class * @return bool */ protected function isBlacklistedEvenWithReferer(string $class): bool { return $this->isBlacklisted($class, static::$evenWithReferer); } }