stavro / arc_ecto

An integration with Arc and Ecto.
255 stars 149 forks source link

[image: {"is invalid", [type: AppName.ImageUploader.Type]}] #81

Open zachbosteel opened 7 years ago

zachbosteel commented 7 years ago

Back in February, I had arc_ecto configured and working just fine to upload images to S3 and save the path to my database. As sometimes happens with projects, the client didn't start using what I had built until earlier this week, and (without any changes to deps or related files since February on my part) things don't seem to work any longer. When I try to upload an image, I get the error mentioned in the title. Here's my ImageUploader file:

defmodule Ekf.ImageUploader do
  use Arc.Definition
  use Arc.Ecto.Definition

  @versions [:original]

  # Whitelist file extensions:
  def validate({file, _}) do
    ~w(.jpg .jpeg .gif .png) |> Enum.member?(Path.extname(file.file_name))
  end
end

Here's my Ecto Model file:

defmodule Ekf.Image do
  use Ekf.Web, :model
  use Arc.Ecto.Schema

  schema "images" do
    belongs_to :static_page, Ekf.StaticPage
    belongs_to :class_page, Ekf.ClassPage
    belongs_to :instructor_page, Ekf.InstructorPage
    field :path, :string
    field :title, :string
    field :alt, :string
    field :label, :string
    field :image, Ekf.ImageUploader.Type

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:path, :title, :alt, :image, :label, :static_page_id, :class_page_id, :instructor_page_id])
    |> cast_attachments(params, [:image])
    |> validate_required([:title, :alt, :image, :label])
  end

  def path_changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:path])
    |> validate_required([:path])
  end
end

Here's the map I'm passing to the changeset method on update, along with a model struct:

%{
label: "page-image",
image: %Plug.Upload{content_type: "image/jpeg", filename: "martial_arts_by_minorityman.jpg", path: "/var/folders/hw/cyd1v_z95l115dr3m5j08l5h0000gn/T//plug-1501/multipart-474368-69450-4"}, 
alt: "A powerful roundhouse kick.", 
title: "Muay Thai",
class_page_id: 2
}

Here's the error I'm getting in its entirety:

#Ecto.Changeset<action: nil, changes: %{},
 errors: [image: {"is invalid", [type: Ekf.ImageUploader.Type]}],
 data: #Ekf.Image<>, valid?: false>

I'm pretty stumped here. It seems as if the custom type has stopped working, and I could see that happening if any of deps had crept, but I really don't think they have. Here are my pinned versions for reference:

  defp deps do
    [{:phoenix, "~> 1.2.0"},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_ecto, "~> 3.0"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:cowboy, "~> 1.0"},
     {:ex_machina, "~> 1.0"},
     {:comeonin, "~> 2.5"},
     {:guardian, "~> 0.13.0"},
     {:arc, "~> 0.5.2"},
     {:arc_ecto, "~> 0.4.4"},
     {:ex_aws, "~> 0.5.0"},
     {:poison, "~> 2.0"},
     {:httpoison, "~> 0.9.0"},
     {:bamboo, "~> 0.8.0"},
     {:bamboo_smtp, "~> 1.3.0"}
    ]
  end

Any help would be much appreciated.

martinthenth commented 7 years ago

Having the same issue: invalid or unknown type error is thrown by Ecto for MyUploader.Type.

** (ArgumentError) invalid or unknown type MyApp.ImageUploader.Type for field :image
    lib/ecto/schema.ex:1727: Ecto.Schema.check_type!/3
    lib/ecto/schema.ex:1431: Ecto.Schema.__field__/4
    lib/accounts/user/user.ex:15: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
shawnonthenet commented 7 years ago

So I had this problem tonight and it ended up being that I had the wrong settings in prod for my IAM token so the upload to s3 was failing.

jhonathas commented 7 years ago

Also here.

nkezhaya commented 7 years ago

Getting this as well. @shawnonthenet can you elaborate on your IAM issue? I only have a single user and key. Works on another dev's machine.

xfumihiro commented 7 years ago

In my case there's something wrong with Imagemagick which cause the conversion step to fail.

Error traced on this line {:error, ["convert: unable to load module '/usr/local/Cellar/imagemagick/7.0.5-10/lib/ImageMagick//modules-Q16HDRI/coders/jpeg.la': file not found @ error/module.c/OpenModule/1266.\nconvert: no decode delegate for this image formatJPEG' @ error/constitute.c/ReadImage/509.\nconvert: no images defined /var/folders/s3/j8_f62kx4dx8g7j_q5rb3my80000gn/T/EMXOWSUFDBT73REVERBBWH7RQ7KASJQU' @ error/convert.c/ConvertImageCommand/3254.\n", "convert: unable to load module '/usr/local/Cellar/imagemagick/7.0.5-10/lib/ImageMagick//modules-Q16HDRI/coders/jpeg.la': file not found @ error/module.c/OpenModule/1266.\nconvert: no decode delegate for this image formatJPEG' @ error/constitute.c/ReadImage/509.\nconvert: no images defined /var/folders/s3/j8_f62kx4dx8g7j_q5rb3my80000gn/T/33GWBMEKZ4WICVJRMGYKZ3W3DYA3YXET' @ error/convert.c/ConvertImageCommand/3254.\n"]}

Everything back to normal after "brew update imagemagick".

nkezhaya commented 7 years ago

@xfumihiro Thanks!! brew update imagemagick fixed it.

aesmail commented 7 years ago

This should have more visibility. Upgrading Imagemagick did the trick as @xfumihiro mentioned.

max-bertinetti commented 7 years ago

(ArgumentError) invalid or unknown type Golfcoupons.PackageImageUploader.Type for field :image lib/ecto/schema.ex:1886: Ecto.Schema.check_type!/3 lib/ecto/schema.ex:1507: Ecto.Schema.field/4 lib/golfcoupons/golf/package.ex:10: (module) (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

I have ImageMagik installed on Linux Mint 18.2 (package version 8:6.8.9.9-7ubuntu5.9)

devnacho commented 6 years ago

I'm having this problem and I can't make it work.

I've uninstalled and reinstalled imagemagick with homebrew and I still get [image: {"is invalid",

Anyone else with this problem or any other possible solution?

denispeplin commented 6 years ago

As it said above, upload failure to S3 causes is invalid error. It is also included in tests: https://github.com/stavro/arc_ecto/blob/d114fe019fcafb7695415bfd9d349e77525baf1f/test/schema_test.exs#L68 So any kind of storage failure will cause is invalid error. Why not raise or propagate adequate error? Image itself is fine, it's just some network error.

denispeplin commented 6 years ago

So I've lost about an hour trying to get a debug to find out why I received is invalid error. Image was fine (size and type), and my validator passed it. But after cast I received is invalid anyway. Errors got swallowed up here: https://github.com/stavro/arc_ecto/blob/master/lib/arc_ecto/type.ex#L20 I put IO.inspect definition.store(args) in the cast function and got the error:

 [{:http_error, 403,
   %{body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the request time and the current time is too large.</Message><RequestTime>20180810T132202Z</RequestTime><ServerTime>2018-08-10T13:37:30Z</ServerTime><MaxAllowedSkewMilliseconds>900000</MaxAllowedSkewMilliseconds><RequestId>B78B31447C732471</RequestId><HostId>...</HostId></Error>",
     headers: [{"x-amz-request-id", "..."},
      {"x-amz-id-2",
       "..."},
      {"Content-Type", "application/xml"}, {"Transfer-Encoding", "chunked"},
      {"Date", "Fri, 10 Aug 2018 13:37:29 GMT"}, {"Server", "AmazonS3"}],
     status_code: 403}}]}

So S3 response was very clear (server clocks went out of sync this time), but because arc_ecto swallowed up the error, it takes too much time to debug it.

Better to raise an error than to handle it that way.