0
votes

I am using try and rescue, but it's not working. When I do this,

iex(3)> try do
...(3)>   File.read! "junaid"
...(3)> rescue
...(3)>   error ->
...(3)>     IO.inspect error
...(3)> end
%File.Error{action: "read file", path: "junaid", reason: :enoent}
%File.Error{action: "read file", path: "junaid", reason: :enoent}

but when I use it with my own method such as

iex(2)> try do                                                     
...(2)>   EvercamMedia.S3.do_save_multiple(%{"junaid" => "junaid"})
...(2)> rescue                                                     
...(2)>    error ->                                                
...(2)>      IO.inspect error                                      
...(2)> end

but it won't work and give me such error

[error] Task #PID<0.1075.0> started from #PID<0.1065.0> terminating
** (File.Error) could not read file "junaid": no such file or directory
    (elixir 1.11.1) lib/file.ex:354: File.read!/1
    (evercam_media 1.0.1607441172) lib/evercam_media/s3.ex:46: anonymous fn/1 in EvercamMedia.S3.do_save_multiple/1

Is it possible to just bypass this error and do_something() in rescue? or in any other clause which says, it's an error? instead of breaking the process?

Why try and rescue don't work in such a way where it will do the work in try and if there is ANY error it will just go to the rescue and don't break the process.

UPDATE: the method, EvercamMedia.S3.do_save_multiple

  def do_save_multiple(paths) do
    upload_file = fn {src_path, dest_path} ->
      ExAws.S3.put_object("evercam-camera-assets", dest_path, File.read!(src_path),
        acl: :public_read
      )
      |> ExAws.request!()
    end

    paths
    |> Task.async_stream(upload_file, max_concurrency: 10, timeout: :infinity)
    |> Stream.run()
  end
1

1 Answers

0
votes

There is a fundamental issue with an attempt to rescue the error here: EvercamMedia.S3.do_save_multiple/1 seems to spawn a task, meaning the code does not raise any error within this process, which makes it meaningless to try to handle it within this process. It’s like trying to catch the flight from Paris to Vienne at Barcelona’s airport.

If you own EvercamMedia.S3.do_save_multiple/1, rescue the error there. If you don’t, you might either trap exits in the calling process and perform whatever you want in handle_info({:EXIT, _, _}, state) callback, or simply spawn it unlinked via e. g. Kernel.spawn/1

spawn(fn ->
  EvercamMedia.S3.do_save_multiple(%{"junaid" => "junaid"})
end)