Problem/Motivation

If we try to access an image that do not exists, we will get a generic "Error generating image".

I believe a 404 not found error is more appropriate.

Steps to reproduce

  1. Install and enable the module.
  2. Try to access /sites/default/files/styles/thumbnail/public/this-image-totally-exists-trust-me-bro.webp.jpg
  3. Get a generic "Error generating image".

Proposed resolution

Add a conditional statement to ImageStyleDownloadController to check if the image exists, and if doesn't, throw a NotFoundHttpException

Remaining tasks

To be added.

User interface changes

None.

API changes

None.

Data model changes

None.

CommentFileSizeAuthor
#2 3556675.patch1.05 KBadinancenci

Issue fork wpf-3556675

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

adinancenci created an issue. See original summary.

adinancenci’s picture

StatusFileSize
new1.05 KB
caesius’s picture

Category: Feature request » Bug report

Our client site's watchdog logs were getting flooded with 'Unable to generate the derived image' messages from crawlers hitting white screens with 'Error generating image.' It turns out this bug not only happens when trying to access an image derivative with .webp.jpg at the end, but any doubled up image extension ending in .jpg will trigger it: .png.jpg, .gif.jpg, .jpg.jpg

This behavior, along with the fact that this module cops Drupal core error messages verbatim and identifies them as coming from the Drupal core image module, obfuscates the fact that it's the unfortunately-named wpf module generating the errors (imagine if more contributed modules identified themselves by acronyms...)

This patch fixes the watchdog logs flooding, but I would propose also updating the controller to properly identify where the error is coming from.

https://git.drupalcode.org/project/wpf/-/blob/1.2.x/src/Controller/Image...

  • Update inherited $this->logger to identify the generating module as wpf not image
  • Update wording for watchdog error: "Unable to generate the derived image" to "Unable to generate the webp fallback image"
  • Update whitescreen error message: "Error generating image." to "Error generating webp fallback image."

eduardo morales alberti made their first commit to this issue’s fork.

eduardo morales alberti’s picture

We encountered this same issue in a project using ImageMagick + file_mdm as the image toolkit. In our case, the missing source check doesn't just produce misleading log entries, it causes an unhandled exception from the file_mdm module.

>When the source image doesn't exist and WPF's deliver() method calls createDerivative(), the following chain triggers:

 $image_style->createDerivative($image_uri, $derivative_uri)
 → \Drupal\Core\Image\ImageFactory::get($source)
 → \Drupal\Core\Image\Image::__construct()
 → $this->getToolkit()->setSource($this->source)
 → $this->getToolkit()->parseFile()
 

With ImageMagick, parseFile() delegates to file_mdm to read metadata:

 // \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::parseFile()
 if (!$file_md->getMetadata(static::FILE_METADATA_PLUGIN_ID)) {
 return FALSE;
 }
 

Which calls FileMetadataPluginBase::loadMetadataFromFile() method:

 // \Drupal\file_mdm\Plugin\FileMetadata\FileMetadataPluginBase::loadMetadataFromFile()
 if (!file_exists($this->getLocalTempPath())) {
 throw new FileNotExistsException("Could not load metadata from '{$this->getLocalTempPath()}' because it does not exist.");
 }
 

Fix:

Drupal core's \Drupal\image\Controller\ImageStyleDownloadController::deliver() prevents this by checking source existence before calling createDerivative() method:

    // Don't try to generate file if source is missing.
    if ($image_uri !== $sample_image_uri && !$this->sourceImageExists($image_uri, $token_is_valid)) {
      // If the image style converted the extension, it has been added to the
      // original file, resulting in filenames like image.png.jpeg. So to find
      // the actual source image, we remove the extension and check if that
      // image exists.
      $converted_image_uri = static::getUriWithoutConvertedExtension($image_uri);
      if ($converted_image_uri !== $image_uri &&
          $this->sourceImageExists($converted_image_uri, $token_is_valid)) {
        // The converted file does exist, use it as the source.
        $image_uri = $converted_image_uri;
      }
      else {
        $this->logger->notice('Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', [
          '%source_image_path' => $image_uri,
          '%derivative_path' => $derivative_uri,
        ]);
        return new Response($this->t('Error generating image, missing source file.'), 404);
      }
    }

Since sourceImageExists() is private in the parent and WPF doesn't have $token_is_valid or $sample_image_uri computed, we applied a simplified version following the same pattern, returning a 404 Response with a notice log.

We also addressed the suggestions from #3 by:

  • Setting the logger channel to 'wpf' instead of inheriting 'image' from the parent.
  • Updating messages to reference "webp fallback image" so they're different from core's image module logs.
eduardo morales alberti’s picture

Status: Active » Needs review

Ready to review

eduardo morales alberti’s picture

We will opt to remove the module, as it is not necessary with modern browsers.