neutronX / django-markdownx

Comprehensive Markdown plugin built for Django
https://neutronx.github.io/django-markdownx/
Other
839 stars 152 forks source link

Handle images with wrong exceptions #270

Open juanignaciosl opened 1 month ago

juanignaciosl commented 1 month ago

In a markdownx field, If you drop a PNG with a .jpg extension, you get a 500. This is the relevant part of the trace:

  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/django/views/generic/edit.py", line 151, in post
    return self.form_valid(form)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/markdownx/views.py", line 81, in form_valid
    image_path = form.save(commit=True)
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/markdownx/forms.py", line 61, in save
    image = self._process_raster(image, image_extension)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/markdownx/forms.py", line 135, in _process_raster
    preped_image.save(thumb_io, extension)
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/PIL/Image.py", line 2439, in save
    save_handler(self, fp, filename)
  File "/home/juanignaciosl/.cache/pypoetry/virtualenvs/backend-8ReMSmSP-py3.11/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 653, in _save
    raise OSError(msg) from e
OSError: cannot write mode RGBA as JPEG
"POST /markdownx/upload/ HTTP/1.1" 500 116391

I've taken a look at the code, and at forms.py the saving is based on the extension:

        preped_image.save(thumb_io, extension)

Maybe there's an opportunity on detecting the type based on the header of the file, instead, but that definitely comes with a cost, so I'm just trying to handle the error. How could I catch it? I've tried by overriding save and others at my ModelAdmin or ModelForm without success. I've also tried to get the markdownx.fileUploadError (to show a decent error message), or markdownx.markdownx.fileUploadBegin to detect it up front, but the handler is not working. This is my js:

let element = document.getElementsByClassName("markdownx");
Object.keys(element).map(key =>
  element[key].addEventListener("markdownx.markdownx.fileUploadBegin", event => console.log("error!")));

(side note: is markdownx.markdownx.fileUploadBegin a typo here? I have also tried with markdownx.fileUploadBegin, it won't work, either).

I understand that this is definitely a corner case, but it'd be great if you could point me in the right direction for handling the error :). Thanks!