6

I want cached a controller that returns a json.. I try this:

$build = array(
  '#cache' => array(
    'contexts' => ['ip'],
  ),
);
return (new CacheableJsonResponse(['test'], 200))->addCacheableDependency(CacheableMetadata::createFromRenderArray($build));

But i get an exception:

LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\Core\Cache\CacheableJsonResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of /Applications/MAMP/htdocs/finder-cms/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).

5

The controller from your question runs without exception:

public function demo() {
  $build = array(
    '#cache' => array(
      'contexts' => ['ip'],
    ),
  );
  return (new CacheableJsonResponse(['test'], 200))->addCacheableDependency(CacheableMetadata::createFromRenderArray($build));
}

Result:

["test"]

To produce the exception you need a controller like this:

public function demo() {

  $build = ['#markup' => 'early rendering'];
  $markup = \Drupal::service('renderer')->render($build);

  $build = array(
    '#cache' => array(
      'contexts' => ['ip'],
    ),
  );
  return (new CacheableJsonResponse(['test'], 200))->addCacheableDependency(CacheableMetadata::createFromRenderArray($build));
}

Result:

LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early.

This may not always be that obvious. Another example is when you try to get an url from an url object, see this answer https://drupal.stackexchange.com/a/187094/47547


Add an URL with cacheable metadata to a response

This is how you avoid the exception, when you render an url for a json response, and at the same time add the correct cache metadata to the response:

  $generated_url = $url->toString(TRUE);
  $response = new CacheableJsonResponse(['url' => $generated_url->getGeneratedUrl()], 200);
  $response->addCacheableDependency($generated_url);
  return $response;
  • ! Ok i fixed: ->toString(TRUE)->getGeneratedUrl() THZZ ::) – BOES Jan 18 '17 at 22:09
  • Why I Can not render html first to be able to put in a JSON example to be printed? – BOES Jan 18 '17 at 22:35
  • see api.drupal.org/api/drupal/… – 4k4 Jan 18 '17 at 22:41
  • ok, is but url problem a bug? Becouse this generate bug also in twig function like: path() or url(). I have a fixed when a custom function twig :( – BOES Jan 18 '17 at 22:59
  • This is not a bug, this is used in twig to get cache metadata. You should do the same, add the url as cacheable dependency to the response. – 4k4 Jan 18 '17 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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