I'm writing a Drupal 8 controller which takes in a media entity, and returns a redirect response to the actual file URL.

It works by finding the file associated with the media entity, and then does this:

      $url = file_create_url($file->getFileUri());

      $response = new CacheableRedirectResponse($url);
      $response->addCacheableDependency($media);
      $response->addCacheableDependency($file);

      return $response;

However, this results in a LogicException: "The controller result claims to be providing relevant cache metadata, but leaked metadata was detected"

Ok, so what's happening is that file_create_url() ends up generating cache metadata, and that cache metadata is not being attached the response object. But it doesn't seem possible for me to do that, because file_create_url just returns a string and not the cache metadata object.

Here's my current workaround, but I'm not sure if this is correct either:

      $context = new RenderContext();
      $url = \Drupal::service('renderer')->executeInRenderContext($context, function () use ($file) {
        return file_create_url($file->getFileUri());
      });

      $response = new CacheableRedirectResponse($url);
      $response->addCacheableDependency($media);
      $response->addCacheableDependency($file);
      if (!$context->isEmpty()) {
        $metadata = $context->pop();
        $response->addCacheableDependency($metadata);
      }

      return $response;

Anyone with more experience with cache metadata know if this is the correct way to handle this situation?

Thank you

up vote 1 down vote accepted

This code seems to be OK to me until file_create_url() is transformed into a service which can handle cacheable metadata like UrlGenerator.

An easier way to avoid this error message would be to return an uncacheable RedirectResponse:

  $url = file_create_url($file->getFileUri());
  $response = new RedirectResponse($url);
  return $response;
  • Thanks. But of course, I do want the response to the cacheable :) – Brian Dec 6 at 20:29

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.