LiveView can't wait for `File.read`, and shows {:error, :enoent} randomly

Hi, before showing a image in my LiveView page, I want to check if this image exist or not
for this reason, I used File.exists?() and File.read, Although the image is in the preset direction but it shows me true or false randomly

this behavior destroys my conditions

if @form.value != nil and file_exist(@form.value) do

and:

  def file_exist(file) do
    Path.join(["apps/mishka_html/priv/static/", file])
    |> File.exists?()
  end

how can I fix this ?

Thanks

Are you in your application changing your working dir?

Also perhaps it’s better to use :code priv_dir/1 instead.

2 Likes

no, I don’t Change my directory, and I print address in each request that is right

Path.join([:code.priv_dir(:mishka_html), "static", image]) |> File.exists?()

I think it can help me, why this has problem with direct address?

By “address” do you mean the absolute path or the relative one? And again, using :code.priv_dir/1 or Application.app_dir/2 will be much more reliable in general.

Using relative pathes will break as soon as you start the application from a different location than its src root.

2 Likes

absolute path, exists in my system !! like

apps/mishka_html/priv/static/uploads/image.png

This is a relative path, not absolute.

Have you tried using :code.priv_dir/1 or Application.app_dir/2 already, they are the ultimative solution to your problem.

2 Likes

yes, but not in this project thanks, it works now

Thanks

I have a question, if this file exists out of my project directory like,

/Users/shahryar/Documents/Programming/media-manager

what is your suggestion ? I think :code.priv_dir/1 or Application.app_dir/2 just cover project directory, yes ?

Be very careful with passing form data to filesystem lookups. You don’t want someone to be able to pass “…/…/config/prod.exs” as a form input and have that show your production configuration and potentially secret tokens.

6 Likes

That looks like a configurable base dir for look ups. Which you then use with Path.absname/1,2.

Make sure to check if the resulting path is indeed within the base dir to avoid the security issues José mentioned.

2 Likes