Problem/Motivation

Whenever possible, responsive images should be built with srcset rather than the <picture> tag (more). Also, Stage File Proxy, S3 File System, and the Flysystem suite of modules are common solutions to file storage. Unfortunately, when relying on proxied services for image files that are being rendered through an image style that will output a srcset image tag, an exception is thrown that breaks the entire page.

Steps to reproduce

  1. Install Drupal with the Responsive Images (core) module.
  2. Create a responsive image style that will output a srcset image tag using this technique. The image styles used within the responsive image style should scale only by one dimension.
  3. Create a content type with an image field.
  4. Set that image field's formatter to be a "responsive image" using the style created in Step 2.
  5. Create a piece of content and upload an image that will use that formatter.
  6. Download and enable the Stage File Proxy contrib module (or any other module that uses a proxied service for storing images) and configure it to point to another origin if a file in the file system does not exist.
  7. Move the image file from Step 5 outside of the current environment's file system, and into the place where the SFP origin points to, in such a way that when using SFP as designed, it would find and download this image file when it realized the current environment's file system didn't yet have it.
  8. Navigate to the node page that should output the image using the responsive image formatter.

Expected result: Upon realizing the file isn't in the current environment's file system, Stage File Proxy should grab it from the origin (assuming it exists there) and should be able to use it when rendering the responsive image.

Actual result: An exception is thrown that breaks the entire page:

LogicException: Could not determine image width for 'public://image-name.jpg' using image style with ID: responsive_image_style. This image style can not be used for a responsive image style mapping using the 'sizes' attribute. in responsive_image_build_source_attributes() (line 391 of core/modules/responsive_image/responsive_image.module).

Notes: This error is not thrown when the responsive image style is configured to output a <picture> element. SFP will work as designed and the page/image will be displayed as expected.

Proposed resolution

Unfortunately, I don't know. Looking for guidance here from those more familiar with this functionality...

I assume that a bug that so heavily relies on a contrib module would normally be that module's problem, but this doesn't quite seem to be the case because the exception never gives SFP a chance to fetch the image. I suppose I could have framed it this way: if the image doesn't exist in the file system, an exception is thrown that breaks the whole page, but I would expect only a broken <img> tag on an otherwise OK page. I didn't because that seems more like a "fix your image" problem than a "developers are going to rely on this to work without issue and it won't" problem.

Remaining tasks

TBD

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Issue fork drupal-2827921

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

guschilds created an issue. See original summary.

jelle_s’s picture

Did you try it with the latest dev version when you filed this issue?
#2822429: template_preprocess_responsive_image() does unnecessary IO by creating Image objects was committed on Nov 1st 2016, and it seems it might have fixed the issue. I tried this using the latest git checkout today and couldn't reproduce the error.

  1. I installed the site using the standard install profile.
  2. I enabled Responsive Image and Stage File Proxy.
  3. I configured the responsive image style:
    langcode: en
    status: true
    dependencies:
      config:
        - image.style.max_1300x1300
        - image.style.max_2600x2600
        - image.style.max_325x325
        - image.style.max_650x650
    id: break_it
    label: 'Break it'
    image_style_mappings:
      -
        breakpoint_id: responsive_image.viewport_sizing
        multiplier: 1x
        image_mapping_type: sizes
        image_mapping:
          sizes: 100vw
          sizes_image_styles:
            - max_1300x1300
            - max_2600x2600
            - max_325x325
            - max_650x650
    breakpoint_group: responsive_image
    fallback_image_style: '_empty image_'
    
  4. I configured stage file proxy (setting the proxy address to the same site but under sites/default/files2 instead of sites/default/files).
  5. I uploaded a file in an article node.
  6. I moved the directory 2016-12 from sites/default/files to sites/default/files2.
  7. I removed the directory sites/default/files/styles.
  8. I loaded the article page and didn't get an Exception.
guschilds’s picture

Issue summary: View changes
Status: Active » Closed (cannot reproduce)

Jelle_S,

I believe you're right and that the patch in #2822429: template_preprocess_responsive_image() does unnecessary IO by creating Image objects has fixed this bug. I'm no longer able to reproduce it. Seeing as that patch was committed before I filed this issue, I must have been mistaken when I thought I was testing on the most recent version of core.

For reference, I think a detail I'd forgotten to mention in the original description (I just updated it) is that the image styles need to only scale by one dimension (width in my case) and not both. Regardless, I'm still not able to reproduce it with that in place.

Thanks for your time!

chrisfree’s picture

Status: Closed (cannot reproduce) » Active

Reopening because I am still able to produce this issue. When the source file for a responsive image style is missing from the local file system, Drupal is unable to determine the width/height of the image and thus, the exception is thrown.

For example, in the following snippet, if the file referenced by $media_entity->field_media_image is missing, the page attempting to include it will bomb.

$media = [
  '#theme' => 'responsive_image',
  '#responsive_image_style_id' => 'content_image',
  '#uri' => $media_entity->field_media_image->entity->getFileUri(),
  '#attributes' => [
    'alt' => $media_entity->field_media_image->alt,
  ],
]; 

We have been able to work around this by forcing a width/height value, like so:

$media = [
  '#theme' => 'responsive_image',
  '#responsive_image_style_id' => 'content_image',
  '#uri' => $media_entity->field_media_image->entity->getFileUri(),
  '#attributes' => [
    'alt' => $media_entity->field_media_image->alt,
  ],
  '#height' => 540,
  '#width' => 960,
]; 

When SFP has had a chance to pull down the source image, for example when visiting the entity's view/edit pages, the page renders without issue. Presumably, because the width/height have been reliably determined within _responsive_image_build_source_attributes().

I'm unsure as to the best path forward, but my gut says that if an image asset is missing from the local filesystem, the responsive image module should simply render a broken image, versus throwing an exception that brings down the entire page.

bkosborne’s picture

Version: 8.3.x-dev » 8.4.x-dev

Still in issue in 8.4 so updating version.

bkosborne’s picture

I created a sister issue to try and solve this in Stage File Proxy as well: #2922292: Support responsive images, because it's not clear who should really be responsible for making this work.

I think it's a little harsh for core to throw an uncaught exception when this happens though. As a site owner, do you really want your site to completely tank when an image file is missing on your server for whatever reason? Wouldn't you rather just a broken image appear?

A more reasonable approach may to log the error & output the image w/o srcset attribute set at all. Instead it would just output the fallback image style.

bkosborne’s picture

Status: Active » Needs review
StatusFileSize
new2.18 KB

Here's a patch that removes the exception and replaces it with an error in the logs.

chrisfree’s picture

Patch tested and so far appears to be working. We just deployed this out to a production site and will report back if we find any issues. Thank you @bkosborne!

chrisfree’s picture

Status: Needs review » Reviewed & tested by the community
catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

It makes sense to make not throw the exception and log the error instead, however I think we should add test coverage here.

markdorison’s picture

Version: 8.4.x-dev » 8.5.x-dev

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

socketwench’s picture

Still a problem here, on 8.6.1 with SFP and flysystem_s3.

chris burge’s picture

Version: 8.6.x-dev » 8.8.x-dev

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

norman.lol’s picture

#7 fixed the fatal on missing images for me on core 8.9.1.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

thirstysix’s picture

Same issue with Drupal 8.9.15

LogicException: Could not determine image width for 'public://.....jpg' using image style with ID: max_1300x1300. This image style can not be used for a responsive image style mapping using the 'sizes' attribute. in _responsive_image_build_source_attributes() (line 434 of web\core\modules\responsive_image\responsive_image.module).

glynster’s picture

This patch resolves the issue for us as well! RTBC +1

chris burge’s picture

Rerolled patch addresses coding standards error.

summit’s picture

Hi, Great! This Patch resolved mij WSOD on homepage D8. Thanks. And please get it in next release, so others don't have this problem.
Thanks for building and rerolling! Greetings, Martijn

xamount’s picture

Patch at #22 works for me

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mikebarkas’s picture

Patch #22 worked for me. RTBC +1

Tested patch with Drupal 9.3.9 and PHP 8.0.16 using Stage File Proxy 8.x-1.2

andregp’s picture

We still need to address #10 and add tests to this issue so +1 to keep it on Needs Work

I tried myself to add some tests for the patch, but the problem is that the code to be tested is inside the responsive_image.module file and I don't know yet how to test code inside *.module files.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

glynster’s picture

RTBC +1 this resolved the problem for us when using proxy file module.

akhoury made their first commit to this issue’s fork.

akhoury’s picture

Assigned: Unassigned » akhoury
abu-zakham’s picture

joshuami’s picture

Issue summary: View changes

This issue occurs with the s3fs module as well and I can confirm that the patch correctly handles the error for that contrib module as well. Updating the issue summary to reflect that a core fix would solve the issue for more than just stage file proxy.

Would something like this need tests? The patch basically shifts the error to the error logs rather than disrupting page render. That seems reasonable.

jhedstrom’s picture

This patch fixes the fatal error, which is great, but it has downstream PHP warning/notice issues as the underlying responsive image code expects certain metadata (width, height) to always be set.

Warning: Undefined array key "width" in template_preprocess_responsive_image() (line 209 of core/modules/responsive_image/responsive_image.module).
template_preprocess_responsive_image(Array, 'responsive_image', Array)
norman.lol’s picture

Assigned: akhoury » Unassigned
thejimbirch’s picture

The patch in #35 fixes the issue for me with no images and with Stage File Proxy on Drupal 10.4.3.

Leaving as Needs Work though for the comments in #37.

berdir made their first commit to this issue’s fork.

prudloff made their first commit to this issue’s fork.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

korn3000’s picture

port patch for 11.3.1

prudloff’s picture

I added a test that fails without the patch.

smustgrave’s picture

Can we turn the test to a kernel.

smustgrave’s picture

Status: Needs review » Needs work

In an effort to go more kernel can we convert that please.