Phoenix 1.7 Show file upload errors

I am using Phoenix 1.7.1. I generated a non-liveview setup with mix phx.gen.html Games Replay replays name:string and then I’m adding file upload on top of that. The following appears to work for getting a file through. If I leave the name out when submitting I get “can’t be blank” by the name field as usual. But if I don’t select a file at all then on submission all I get is “Oops, something went wrong! Please check the errors below.” at the very top without any specific message. How am I suppose to arrange for an error to appear by the file upload elements?

<.simple_form :let={f} for={@changeset} action={@action} multipart>
  <.error :if={@changeset.action}>
    Oops, something went wrong! Please check the errors below.
  </.error>
  <.input field={f[:name]} type="text" label="Name" />

  <.label>Replay</.label>
  <%= Phoenix.HTML.Form.file_input(f, :replay_file) %>

  <:actions>
    <.button>Save Replay</.button>
  </:actions>
</.simple_form>

What happens if you change this:

 <.label>Replay</.label>
 <%= Phoenix.HTML.Form.file_input(f, :replay_file) %>

…to this?

<.input field={f[:replay_file]} type="file" label="Replay" />

The <.input> component should be able to handle file inputs automatically, and if you want to customize the look and feel you can add another clause to your CoreComponents module:

  def input(%{type: "file"} = assigns) do
    ~H"""
    (your custom file input)
    """
  end
1 Like

See if it gives you any chance: <.error :for={msg <- f[:replay_file].errors}><%= inspect(msg) %></.error>. Upload errors might be a bit complex, so regular <%= msg %> may initially fail, so wrapping it with inspect would give you a chance to adapt it to your changeset error format.

Edit: This is actually what translate_error takes care of.

Does

actually bring <.live_file_input to the fore? Then this would cover all the styling as well around the actual erroneous input?

No, and the question is specifically not about LiveView. :slight_smile: Setting type="file" on the input component renders <input type="file" ...> in the exact same way that setting type="text" renders <input type="text" ...>.

Further, the errors will be related to the Changeset and not the upload, so they should not require any further translation.

1 Like

Ah I see the default implementation of input component handles this file type just fine. I just tried out the following and it worked to show an error message.

<.input field={f[:file]} type="file" label="Replay" />
1 Like