Occasionally I get failures like this one but they provide no context as to which image failed making it difficult to debug when they are popping up occasionally on a busy web server. I don't know why this wouldn't have been included unless in this wrapper that details (such as the filename) was not available?
[ERROR] Thumbnail tag failed [thumbnail:84]
Traceback (most recent call last):
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 59, in render
return self._render(context)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 137, in _render
thumbnail = get_thumbnail(file_, geometry, **options)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/shortcuts.py", line 8, in get_thumbnail
return default.backend.get_thumbnail(file_, geometry_string, **options)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/base.py", line 125, in get_thumbnail
thumbnail)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/base.py", line 157, in _create_thumbnail
image = default.engine.create(source_image, geometry, options)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/engines/base.py", line 20, in create
image = self.orientation(image, geometry, options)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/engines/base.py", line 45, in orientation
return self._orientation(image)
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/engines/pil_engine.py", line 71, in _orientation
exif = image._getexif()
File "/app/.heroku/python/lib/python2.7/site-packages/PIL/JpegImagePlugin.py", line 390, in _getexif
return _getexif(self)
File "/app/.heroku/python/lib/python2.7/site-packages/PIL/JpegImagePlugin.py", line 418, in _getexif
info = TiffImagePlugin.ImageFileDirectory(head)
File "/app/.heroku/python/lib/python2.7/site-packages/PIL/TiffImagePlugin.py", line 274, in __init__
raise SyntaxError("not a TIFF IFD")
For anyone finding this error message, I've also filed a bug with Pillow with this error in getting EXIF:
@mariocesar Can you recommend a solution here? Some users upload images to my site which are corrupted somehow, and subsequently I get this error logging popping up all of the time.
@mariocesar Please.
Yeah, please! =D
The problem was in fact a bug in the watermarking program these users were using resulting in corrupt EXIF, and I worked with the author to get that fixed.
The way I solved this issue was to always generate these thumbs in code (rather than template), and wrap in a try block. Additionally, I have a periodic process that tries to generate the thumbs rather than during the request cycle. If there's a problem with the image I log it with the necessary info, and remove the image so that the failure doesn't keep happening.
def get_thumbnail(self, dims, upscale=False, **options):
""" Use sorl to produce the thumbnail; this also caches it for later.
"""
from sorl.thumbnail import get_thumbnail as sorl_get_thumbnail
try:
return sorl_get_thumbnail(self.best_image(), dims, upscale=upscale, **options)
except SyntaxError:
# Only catch SyntaxError: not a tiff, otherwise, I had Heroku rebooting
# and caused me to remove a good image.
log.error("Problem generating thumbnail for #%s @ %s. Removed it. %s",
self.id, dims, self.best_image().url, exc_info=True)
# Remove all images.
self.image = ""
self.save()
return None
File "/app/.heroku/python/lib/python2.7/site-packages/sorl/thumbnail/engines/pil_engine.py", line 71, in _orientation
exif = image._getexif()
`` python
def _orientation(self, image):
try:
exif = image._getexif()
except (AttributeError, IOError, KeyError, IndexError):
exif = None
if exif:
orientation = exif.get(0x0112)
if orientation == 2:
image = image.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 3:
image = image.rotate(180)
elif orientation == 4:
image = image.transpose(Image.FLIP_TOP_BOTTOM)
elif orientation == 5:
image = image.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 6:
image = image.rotate(-90)
elif orientation == 7:
image = image.rotate(90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 8:
image = image.rotate(90)
return image
why except (AttributeError, IOError, KeyError, IndexError) ?
we got a SyntaxError("not a TIFF IFD") , not in the error list, this is the bug.
why not just except Exception ??
if could not get exif, just ignore, keep going.
all right , they have already removed the bug.
def _orientation(self, image):
try:
exif = image._getexif()
except:
exif = None