mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-11-09 13:44:53 +08:00
Gracefully handle errors in the inspect protocol (#934)
This commit is contained in:
parent
928cb5c592
commit
6b19f1d71b
3 changed files with 40 additions and 5 deletions
|
|
@ -35,14 +35,13 @@ defmodule Livebook.Evaluator.DefaultFormatter do
|
||||||
defp to_output(value) do
|
defp to_output(value) do
|
||||||
# Kino is a "client side" extension for Livebook that may be
|
# Kino is a "client side" extension for Livebook that may be
|
||||||
# installed into the runtime node. If it is installed we use
|
# installed into the runtime node. If it is installed we use
|
||||||
# its more precies output rendering rules.
|
# its more precise output rendering rules.
|
||||||
if Code.ensure_loaded?(Kino.Render) do
|
if Code.ensure_loaded?(Kino.Render) do
|
||||||
try do
|
try do
|
||||||
Kino.Render.to_livebook(value)
|
Kino.Render.to_livebook(value)
|
||||||
catch
|
catch
|
||||||
kind, error ->
|
kind, error ->
|
||||||
{error, stacktrace} = Exception.blame(kind, error, __STACKTRACE__)
|
formatted = format_error(kind, error, __STACKTRACE__)
|
||||||
formatted = Exception.format(kind, error, stacktrace)
|
|
||||||
Logger.error(formatted)
|
Logger.error(formatted)
|
||||||
to_inspect_output(value)
|
to_inspect_output(value)
|
||||||
end
|
end
|
||||||
|
|
@ -52,8 +51,19 @@ defmodule Livebook.Evaluator.DefaultFormatter do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp to_inspect_output(value, opts \\ []) do
|
defp to_inspect_output(value, opts \\ []) do
|
||||||
inspected = inspect(value, inspect_opts(opts))
|
try do
|
||||||
{:text, inspected}
|
inspected = inspect(value, inspect_opts(opts))
|
||||||
|
{:text, inspected}
|
||||||
|
catch
|
||||||
|
kind, error ->
|
||||||
|
formatted = format_error(kind, error, __STACKTRACE__)
|
||||||
|
{:error, formatted, :other}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp format_error(kind, error, stacktrace) do
|
||||||
|
{error, stacktrace} = Exception.blame(kind, error, stacktrace)
|
||||||
|
Exception.format(kind, error, stacktrace)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inspect_opts(opts) do
|
defp inspect_opts(opts) do
|
||||||
|
|
|
||||||
16
test/livebook/evaluator/default_formatter_test.exs
Normal file
16
test/livebook/evaluator/default_formatter_test.exs
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
defmodule Livebook.Evaluator.DefaultFormatterTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
alias Livebook.Evaluator.DefaultFormatter
|
||||||
|
|
||||||
|
test "inspects successful results" do
|
||||||
|
result = 10
|
||||||
|
assert {:text, "\e[34m10\e[0m"} = DefaultFormatter.format_response({:ok, result})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "gracefully handles errors in the inspect protocol" do
|
||||||
|
result = %Livebook.TestModules.BadInspect{}
|
||||||
|
assert {:error, error, :other} = DefaultFormatter.format_response({:ok, result})
|
||||||
|
assert error =~ ":bad_return"
|
||||||
|
end
|
||||||
|
end
|
||||||
9
test/support/test_modules/bad_inspect.ex
Normal file
9
test/support/test_modules/bad_inspect.ex
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Livebook.TestModules.BadInspect do
|
||||||
|
defstruct []
|
||||||
|
|
||||||
|
defimpl Inspect do
|
||||||
|
def inspect(%Livebook.TestModules.BadInspect{}, _opts) do
|
||||||
|
:bad_return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Reference in a new issue