【问题标题】:How to handle try and rescue errors in Elixir如何处理 Elixir 中的尝试和救援错误
【发布时间】:2020-12-09 14:57:25
【问题描述】:

我正在使用尝试和救援,但它不起作用。当我这样做时,

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}

但是当我用自己的方法使用它时,例如

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

但它不起作用并给我这样的错误

[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

是否可以在救援中绕过这个错误和do_something()?或在任何其他条款中说,这是一个错误?而不是中断流程?

为什么 try 和 rescue 不能以这样的方式工作,它会在 try 中完成工作,如果有任何错误,它只会去救援并且不会破坏过程。

更新:方法,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

【问题讨论】:

    标签: elixir


    【解决方案1】:

    这里试图挽救错误存在一个根本问题:EvercamMedia.S3.do_save_multiple/1 似乎产生了一个任务,这意味着代码在此过程中不会引发任何错误,这使得在这个过程中尝试处理它变得毫无意义。这就像在巴塞罗那机场赶从巴黎飞往维也纳的航班。

    如果您拥有EvercamMedia.S3.do_save_multiple/1,请在此处挽救错误。如果你不这样做,你可以在调用过程中 trap exits 并在 handle_info({:EXIT, _, _}, state) 回调中执行你想要的任何操作,或者简单地通过 e 将其生成为取消链接。 G。 Kernel.spawn/1

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

    【讨论】:

    • 但我实际上想捕获错误,然后在数据库中记录一些内容。
    • 您无法从其他进程中捕获错误。此外,您无法从不同的进程访问 anything。您只能①在那里发送/接收消息,②在其他进程退出时得到通知(当且仅当您的进程链接到另一个进程并且陷阱退出,如我上面链接的那样。)
    猜你喜欢
    • 2017-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多