mikera / imagez

Image processing library for Clojure
302 stars 38 forks source link

Better exception for mikera.image.core/load-image when file isn't a valid image? #32

Open benkamphaus opened 8 years ago

benkamphaus commented 8 years ago

Ran into this issue where a file system glob pulled in an invalid file that didn't contain an image. At present, if you try to load an invalid image file you get an NPE, for example with a fairly minimal repro (copying README.md to resource in a vanilla Leiningen project):

(ns imagez-repro.core
  (:require [mikera.image.core :as img]))

(-> (clojure.java.io/resource "README.md")
     clojure.java.io/file
     img/load-image)

produces:

clojure.lang.Compiler$CompilerException: java.lang.NullPointerException

                          clojure.core/eval/invokeStatic  core.clj: 3105
                                                     ...
                            mikera.image.core/load-image  core.clj:   77
               mikera.image.core/load-image/invokeStatic  core.clj:   86
             mikera.image.core/ensure-default-image-type  core.clj:   66
mikera.image.core/ensure-default-image-type/invokeStatic  core.clj:   70
         java.lang.NullPointerException:
clojure.lang.Compiler$CompilerException: java.lang.NullPointerException, compiling:(form-init1473572426971639384.clj:1:9)

It seems like this case could be caught and handled with a more idiomatic Exception? I could take a stab at it given agreement and consensus around what the Exception should be.

mikera commented 8 years ago

Agree. It should probably be a java.io.FileNotFoundException, I think?

With a message indicating that the file argument was null, perhaps?

simon-brooke commented 8 years ago

I'm seeing the same thing, by a slightly more convoluted route, since upgrading to 0.11.0

I had been using fivetonine.collage.util to actually load the images, but that loads a java.awt.image.BufferedImage which imagez 0.11.0 doesn't like, so I attempted a change to load-image-resource:

     (let [heightmap (imagez/filter-image
                       (filters/grayscale)
-                      (collage/load-image imagepath))]
+                      (imagez/load-image-resource imagepath))]

And this results in an illegal argument exception which is caused by a null pointer:

ERROR in (apply-heightmap-test) (core_deftype.clj:568)  
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No implementation of method: :as-image of protocol: #'mikera.image.protocols/ImageResource found for class: nil
 at clojure.core$_cache_protocol_fn.invokeStatic (core_deftype.clj:568)
    clojure.core$_cache_protocol_fn.invoke (core_deftype.clj:560)
    mikera.image.protocols$eval1366$fn__1367$G__1357__1372.invoke (protocols.clj:15)

Actually I think this may be a different but related exception, in that it's possible that the file path that worked with collage isn't working with imagez so may not actually find a file at all, as the file I'm expecting it to find is a perfectly good PNG.

simon-brooke commented 8 years ago

Ignore me. It's just that you'd swapped the order of arguments to filter-image!