From 56734420a07c8a1061aa97d283f13bc36ef92eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 15 Nov 2023 18:54:27 +0100 Subject: [PATCH] Only keep #cell: markers in stacktrace (#2351) --- lib/livebook/runtime/evaluator/doctests.ex | 2 +- lib/livebook/runtime/evaluator/formatter.ex | 25 ++++++++++++++++++++- test/livebook/runtime/evaluator_test.exs | 11 +++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/livebook/runtime/evaluator/doctests.ex b/lib/livebook/runtime/evaluator/doctests.ex index 6e895d9b5..82a5b05b8 100644 --- a/lib/livebook/runtime/evaluator/doctests.ex +++ b/lib/livebook/runtime/evaluator/doctests.ex @@ -334,7 +334,7 @@ defmodule Livebook.Runtime.Evaluator.Doctests do end defp format_stacktrace_entry(entry, _test_case, _test) do - Exception.format_stacktrace_entry(entry) + Livebook.Runtime.Evaluator.Formatter.format_stacktrace_entry(entry) end defp format_label(label), do: colorize(:cyan, "#{label}:") diff --git a/lib/livebook/runtime/evaluator/formatter.ex b/lib/livebook/runtime/evaluator/formatter.ex index eb3aa3d9e..2e4f0032b 100644 --- a/lib/livebook/runtime/evaluator/formatter.ex +++ b/lib/livebook/runtime/evaluator/formatter.ex @@ -133,13 +133,36 @@ defmodule Livebook.Runtime.Evaluator.Formatter do if stacktrace == [] do banner else - stacktrace = Exception.format_stacktrace(stacktrace) + stacktrace = format_stacktrace(stacktrace) [banner, "\n", error_color(stacktrace)] end IO.iodata_to_binary(message) end + defp format_stacktrace(trace) do + case trace do + [] -> "\n" + _ -> " " <> Enum.map_join(trace, "\n ", &format_stacktrace_entry(&1)) <> "\n" + end + end + + @doc """ + Formats a stacktrace entry keeping only the #cell: bits. + """ + def format_stacktrace_entry(entry) do + entry = + with {mod, fun, arity, info} <- entry, + [_ | _] = file <- info[:file], + [_, cell] <- :string.split(file, "#cell:") do + {mod, fun, arity, Keyword.put(info, :file, ~c"#cell:" ++ cell)} + else + _ -> entry + end + + Exception.format_stacktrace_entry(entry) + end + defp blame_match(%{match?: true, node: node}), do: Macro.to_string(node) defp blame_match(%{match?: false, node: node}) do diff --git a/test/livebook/runtime/evaluator_test.exs b/test/livebook/runtime/evaluator_test.exs index 71e2cc272..9458318a1 100644 --- a/test/livebook/runtime/evaluator_test.exs +++ b/test/livebook/runtime/evaluator_test.exs @@ -195,6 +195,17 @@ defmodule Livebook.Runtime.EvaluatorTest do """ <> _ = clean_message(message) end + test "only keeps #cell: markers in stacktrace", %{evaluator: evaluator} do + code = """ + List.first(%{}) + """ + + Evaluator.evaluate_code(evaluator, :elixir, code, :code_1, [], file: "file.ex#cell:abcDEF") + + assert_receive {:runtime_evaluation_response, :code_1, error(message), metadata()} + assert message =~ " #cell:abcDEF:1: (file)" + end + test "returns additional metadata when there is a syntax error", %{evaluator: evaluator} do code = "1+"