Make failed evaluations preserve evaluation context (#145)

This commit is contained in:
Jonatan Kłosko 2021-04-05 17:01:07 +02:00 committed by GitHub
parent 051156588d
commit b3661ed2f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 11 deletions

View file

@ -121,19 +121,22 @@ defmodule Livebook.Evaluator do
file = Keyword.get(opts, :file, "nofile")
context = put_in(context.env.file, file)
case eval(code, context.binding, context.env) do
{:ok, result, binding, env} ->
result_context = %{binding: binding, env: env}
new_contexts = Map.put(state.contexts, ref, result_context)
new_state = %{state | contexts: new_contexts}
{result_context, response} =
case eval(code, context.binding, context.env) do
{:ok, result, binding, env} ->
result_context = %{binding: binding, env: env}
response = {:ok, result}
{result_context, response}
send_evaluation_response(send_to, ref, {:ok, result}, state.formatter)
{:noreply, new_state}
{:error, kind, error, stacktrace} ->
response = {:error, kind, error, stacktrace}
{context, response}
end
{:error, kind, error, stacktrace} ->
send_evaluation_response(send_to, ref, {:error, kind, error, stacktrace}, state.formatter)
{:noreply, state}
end
send_evaluation_response(send_to, ref, response, state.formatter)
new_state = put_in(state.contexts[ref], result_context)
{:noreply, new_state}
end
def handle_cast({:forget_evaluation, ref}, state) do

View file

@ -109,6 +109,30 @@ defmodule Livebook.EvaluatorTest do
end)
end
test "in case of an error uses own evaluation context as the resulting context",
%{evaluator: evaluator} do
code1 = """
x = 2
"""
code2 = """
raise ":<"
"""
code3 = """
x * x
"""
Evaluator.evaluate_code(evaluator, self(), code1, :code_1)
assert_receive {:evaluation_response, :code_1, {:ok, _}}
Evaluator.evaluate_code(evaluator, self(), code2, :code_2, :code_1)
assert_receive {:evaluation_response, :code_2, {:error, _, _, _}}
Evaluator.evaluate_code(evaluator, self(), code3, :code_3, :code_2)
assert_receive {:evaluation_response, :code_3, {:ok, 4}}
end
test "given file option sets it in evaluation environment", %{evaluator: evaluator} do
code = """
__DIR__