如何处理 Elixir 中的尝试和救援错误
How to handle try and rescue errors in Elixir
我正在使用 try and rescue,但它不起作用。当我这样做时,
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
试图挽救这里的错误存在一个根本问题:EvercamMedia.S3.do_save_multiple/1
似乎 产生了一个任务 ,这意味着代码不会引发任何错误 within this process,这使得试图在这个进程中处理它变得毫无意义。这就像试图在巴塞罗那机场赶上从巴黎飞往维也纳的航班。
如果您拥有 EvercamMedia.S3.do_save_multiple/1
,请修复那里的错误。如果你不这样做,你可能 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)
我正在使用 try and rescue,但它不起作用。当我这样做时,
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
试图挽救这里的错误存在一个根本问题:EvercamMedia.S3.do_save_multiple/1
似乎 产生了一个任务 ,这意味着代码不会引发任何错误 within this process,这使得试图在这个进程中处理它变得毫无意义。这就像试图在巴塞罗那机场赶上从巴黎飞往维也纳的航班。
如果您拥有 EvercamMedia.S3.do_save_multiple/1
,请修复那里的错误。如果你不这样做,你可能 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)