Skip to content

Commit 7d100ff

Browse files
committed
Always log errors at the end of compilation
1 parent 6b69c7f commit 7d100ff

File tree

4 files changed

+46
-28
lines changed

4 files changed

+46
-28
lines changed

lib/elixir/lib/kernel/parallel_compiler.ex

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,11 @@ defmodule Kernel.ParallelCompiler do
455455
# No more queue, nothing waiting, this cycle is done
456456
defp spawn_workers([], spawned, waiting, files, result, warnings, errors, state)
457457
when map_size(spawned) == 0 and map_size(waiting) == 0 do
458+
# Print any spurious error that we may have found
459+
Enum.map(errors, fn {diagnostic, read_snippet} ->
460+
:elixir_errors.print_diagnostic(diagnostic, read_snippet)
461+
end)
462+
458463
[] = files
459464
cycle_return = each_cycle_return(state.each_cycle.())
460465
state = cycle_timing(result, state)
@@ -509,8 +514,9 @@ defmodule Kernel.ParallelCompiler do
509514
if deadlocked do
510515
spawn_workers(deadlocked, spawned, waiting, files, result, warnings, errors, state)
511516
else
512-
deadlock_errors = handle_deadlock(waiting, files)
513-
{return_error(deadlock_errors ++ errors, warnings), state}
517+
return_error(warnings, errors, state, fn ->
518+
handle_deadlock(waiting, files)
519+
end)
514520
end
515521
end
516522

@@ -680,12 +686,13 @@ defmodule Kernel.ParallelCompiler do
680686
state = %{state | timer_ref: timer_ref}
681687
spawn_workers(queue, spawned, waiting, files, result, warnings, errors, state)
682688

683-
{:diagnostic, %{severity: :warning} = diagnostic} ->
684-
warnings = [Module.ParallelChecker.format_diagnostic_file(diagnostic) | warnings]
689+
{:diagnostic, %{severity: :warning, file: file} = diagnostic, read_snippet} ->
690+
:elixir_errors.print_diagnostic(diagnostic, read_snippet)
691+
warnings = [%{diagnostic | file: file && Path.absname(file)} | warnings]
685692
wait_for_messages(queue, spawned, waiting, files, result, warnings, errors, state)
686693

687-
{:diagnostic, %{severity: :error} = diagnostic} ->
688-
errors = [Module.ParallelChecker.format_diagnostic_file(diagnostic) | errors]
694+
{:diagnostic, %{severity: :error} = diagnostic, read_snippet} ->
695+
errors = [{diagnostic, read_snippet} | errors]
689696
wait_for_messages(queue, spawned, waiting, files, result, warnings, errors, state)
690697

691698
{:file_ok, child_pid, ref, file, lexical} ->
@@ -705,10 +712,13 @@ defmodule Kernel.ParallelCompiler do
705712
spawn_workers(queue, new_spawned, waiting, new_files, result, warnings, errors, state)
706713

707714
{:file_error, child_pid, file, {kind, reason, stack}} ->
708-
print_error(file, kind, reason, stack)
709715
{_file, _new_spawned, new_files} = discard_file_pid(spawned, files, child_pid)
710716
terminate(new_files)
711-
{return_error([to_error(file, kind, reason, stack) | errors], warnings), state}
717+
718+
return_error(warnings, errors, state, fn ->
719+
print_error(file, kind, reason, stack)
720+
[to_error(file, kind, reason, stack)]
721+
end)
712722

713723
{:DOWN, ref, :process, pid, reason} when is_map_key(spawned, ref) ->
714724
# async spawned processes have no file, so we always have to delete the ref directly
@@ -717,18 +727,27 @@ defmodule Kernel.ParallelCompiler do
717727
{file, spawned, files} = discard_file_pid(spawned, files, pid)
718728

719729
if file do
720-
print_error(file.file, :exit, reason, [])
721730
terminate(files)
722-
{return_error([to_error(file.file, :exit, reason, []) | errors], warnings), state}
731+
732+
return_error(warnings, errors, state, fn ->
733+
print_error(file.file, :exit, reason, [])
734+
[to_error(file.file, :exit, reason, [])]
735+
end)
723736
else
724737
wait_for_messages(queue, spawned, waiting, files, result, warnings, errors, state)
725738
end
726739
end
727740
end
728741

729-
defp return_error(errors, warnings) do
742+
defp return_error(warnings, errors, state, fun) do
743+
errors =
744+
Enum.map(errors, fn {%{file: file} = diagnostic, read_snippet} ->
745+
:elixir_errors.print_diagnostic(diagnostic, read_snippet)
746+
%{diagnostic | file: file && Path.absname(file)}
747+
end)
748+
730749
info = %{compile_warnings: Enum.reverse(warnings), runtime_warnings: []}
731-
{:error, Enum.reverse(errors), info}
750+
{{:error, Enum.reverse(errors, fun.()), info}, state}
732751
end
733752

734753
defp update_result(result, kind, module, value) do

lib/elixir/lib/module/parallel_checker.ex

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,9 @@ defmodule Module.ParallelChecker do
167167

168168
defp collect_results(count, diagnostics) do
169169
receive do
170-
{:diagnostic, diagnostic} ->
171-
diagnostic = format_diagnostic_file(diagnostic)
170+
{:diagnostic, %{file: file} = diagnostic, read_snippet} ->
171+
:elixir_errors.print_diagnostic(diagnostic, read_snippet)
172+
diagnostic = %{diagnostic | file: file && Path.absname(file)}
172173
collect_results(count, [diagnostic | diagnostics])
173174

174175
{__MODULE__, _module, new_diagnostics} ->
@@ -287,11 +288,6 @@ defmodule Module.ParallelChecker do
287288
end
288289
end
289290

290-
@doc false
291-
def format_diagnostic_file(%{file: file} = diagnostic) do
292-
%{diagnostic | file: file && Path.absname(file)}
293-
end
294-
295291
## Warning helpers
296292

297293
defp group_warnings(warnings) do

lib/elixir/src/elixir_errors.erl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,17 @@ emit_diagnostic(Severity, Position, File, Message, Stacktrace, Options) ->
115115
},
116116

117117
case get(elixir_code_diagnostics) of
118-
undefined -> print_diagnostic(Diagnostic, ReadSnippet);
119-
{Tail, true} -> put(elixir_code_diagnostics, {[print_diagnostic(Diagnostic, ReadSnippet) | Tail], true});
120-
{Tail, false} -> put(elixir_code_diagnostics, {[Diagnostic | Tail], false})
121-
end,
118+
undefined ->
119+
case get(elixir_compiler_info) of
120+
undefined -> print_diagnostic(Diagnostic, ReadSnippet);
121+
{CompilerPid, _} -> CompilerPid ! {diagnostic, Diagnostic, ReadSnippet}
122+
end;
123+
124+
{Tail, true} ->
125+
put(elixir_code_diagnostics, {[print_diagnostic(Diagnostic, ReadSnippet) | Tail], true});
122126

123-
case get(elixir_compiler_info) of
124-
undefined -> ok;
125-
{CompilerPid, _} -> CompilerPid ! {diagnostic, Diagnostic}
127+
{Tail, false} ->
128+
put(elixir_code_diagnostics, {[Diagnostic | Tail], false})
126129
end,
127130

128131
ok.

lib/elixir/test/elixir/kernel/parallel_compiler_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ defmodule Kernel.ParallelCompilerTest do
327327
msg =
328328
capture_io(:stderr, fn ->
329329
fixtures = [foo, bar]
330-
assert {:error, [foo_error, bar_error], []} = Kernel.ParallelCompiler.compile(fixtures)
330+
assert {:error, [bar_error, foo_error], []} = Kernel.ParallelCompiler.compile(fixtures)
331331
assert bar_error == {bar, nil, "deadlocked waiting on module FooDeadlock"}
332332
assert foo_error == {foo, nil, "deadlocked waiting on module BarDeadlock"}
333333
end)
@@ -415,7 +415,7 @@ defmodule Kernel.ParallelCompilerTest do
415415

416416
capture_io(:stderr, fn ->
417417
fixtures = [foo, bar]
418-
assert {:error, [foo_error, bar_error], []} = Kernel.ParallelCompiler.compile(fixtures)
418+
assert {:error, [bar_error, foo_error], []} = Kernel.ParallelCompiler.compile(fixtures)
419419
assert {^bar, nil, "deadlocked waiting on module FooAsyncDeadlock"} = bar_error
420420
assert {^foo, nil, "deadlocked waiting on pmap [#PID<" <> _} = foo_error
421421
end)

0 commit comments

Comments
 (0)