diff --git a/apps/expert_credo/lib/expert_credo.ex b/apps/expert_credo/lib/expert_credo.ex index f62febe5e..225dfd8fc 100644 --- a/apps/expert_credo/lib/expert_credo.ex +++ b/apps/expert_credo/lib/expert_credo.ex @@ -65,15 +65,25 @@ defmodule ExpertCredo do {:ok, stdio} = StringIO.open(stdin_contents) caller = self() - spawn(fn -> - Process.group_leader(self(), stdio) - result = function.() - send(caller, {:result, result}) - end) + {pid, ref} = + spawn_monitor(fn -> + Process.group_leader(self(), stdio) + result = function.() + send(caller, {:result, result}) + end) receive do {:result, result} -> + Process.demonitor(ref, [:flush]) {:ok, result} + + {:DOWN, ^ref, :process, ^pid, reason} -> + {:error, reason} + after + 30_000 -> + Process.demonitor(ref, [:flush]) + Process.exit(pid, :kill) + {:error, :timeout} end end diff --git a/apps/expert_credo/test/expert_credo_test.exs b/apps/expert_credo/test/expert_credo_test.exs index 0a94e7e2f..abf7beb55 100644 --- a/apps/expert_credo/test/expert_credo_test.exs +++ b/apps/expert_credo/test/expert_credo_test.exs @@ -14,6 +14,15 @@ defmodule ExpertCredoTest do Document.new("file:///file.ex", contents, 1) end + test "with_stdin returns result on success" do + assert {:ok, :hello} = ExpertCredo.with_stdin("input", fn -> :hello end) + end + + test "with_stdin returns error when function raises" do + assert {:error, {%RuntimeError{message: "boom"}, _stacktrace}} = + ExpertCredo.with_stdin("input", fn -> raise "boom" end) + end + test "reports errors on documents" do has_inspect = """