Include errors in exported notebook outputs (#3009)

This commit is contained in:
Jonatan Kłosko 2025-05-26 13:42:09 +02:00 committed by GitHub
parent 9d401b56f5
commit 7315cc9f7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 6 deletions

View file

@ -238,12 +238,11 @@ defmodule Livebook.LiveMarkdown.Export do
end
defp render_output(%{type: :terminal_text, text: text}, _ctx) do
text = String.replace_suffix(text, "\n", "")
delimiter = MarkdownHelpers.code_block_delimiter(text)
text = strip_ansi(text)
render_text_output(text)
end
[delimiter, "\n", text, "\n", delimiter]
|> prepend_metadata(%{output: true})
defp render_output(%{type: :error, message: message}, _ctx) do
render_text_output(message)
end
defp render_output(%{type: :js, js_view: %{ref: ref}}, ctx) do
@ -279,6 +278,14 @@ defmodule Livebook.LiveMarkdown.Export do
defp render_output(_output, _ctx), do: :ignored
defp render_text_output(text) do
text = text |> strip_ansi() |> String.replace_suffix("\n", "")
delimiter = MarkdownHelpers.code_block_delimiter(text)
[delimiter, "\n", text, "\n", delimiter]
|> prepend_metadata(%{output: true})
end
defp encode_js_data(data) when is_binary(data), do: {:ok, data}
defp encode_js_data(data) do
@ -349,7 +356,7 @@ defmodule Livebook.LiveMarkdown.Export do
string
|> Livebook.Utils.ANSI.parse_ansi_string()
|> elem(0)
|> Enum.map(fn {_modifiers, string} -> string end)
|> Enum.map_join(fn {_modifiers, string} -> string end)
end
defp render_notebook_footer(_notebook, _notebook_source, _include_stamp? = false), do: {[], []}

View file

@ -947,6 +947,57 @@ defmodule Livebook.LiveMarkdown.ExportTest do
assert expected_document == document
end
test "includes error outputs" do
notebook = %{
Notebook.new()
| name: "My Notebook",
sections: [
%{
Notebook.Section.new()
| name: "Section 1",
cells: [
%{
Notebook.Cell.new(:code)
| source: """
raise "hello"\
""",
outputs: [
{0,
%{
type: :error,
message:
"\e[31m** (RuntimeError) hello\e[0m\n\e[31m #cell:tlbdimkdsfldvwge:1: (file)\n\e[0m",
context: nil
}}
]
}
]
}
]
}
expected_document = """
# My Notebook
## Section 1
```elixir
raise "hello"
```
<!-- livebook:{"output":true} -->
```
** (RuntimeError) hello
#cell:tlbdimkdsfldvwge:1: (file)
```
"""
{document, []} = Export.notebook_to_livemd(notebook, include_outputs: true)
assert expected_document == document
end
test "includes outputs when notebook has :persist_outputs set" do
notebook = %{
Notebook.new()