Files
rose-ash/next/kernel/sandbox.erl
giles e8ca0590a3
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
fed-sx-m1: Step 7d-pure — sandbox:eval_pure/2,/3 + 13 tests
2026-05-28 19:26:34 +00:00

42 lines
1.5 KiB
Erlang

-module(sandbox).
-export([eval_pure/2, eval_pure/3]).
%% Sandboxed evaluation of an Erlang fun.
%%
%% eval_pure/2(Fun, Arg) -> {ok, Result} | {error, Reason}
%% eval_pure/3(Fun, Arg1, Arg2) -> {ok, Result} | {error, Reason}
%%
%% The 3-arity variant matches the (Activity, State) -> NewState
%% shape of projection folds. The projection scheduler can wrap
%% every fold call in `sandbox:eval_pure(Fun, Act, State)` to
%% ensure a misbehaving fold body can't crash the projection
%% gen_server.
%%
%% v1 sandboxing is just the try/catch envelope: no gas budget,
%% no IO denial, no environment stripping. Real sandboxing lands
%% with SX-source eval (the fold body would then be an SX form
%% evaluated under the spec/harness platform). The API shape is
%% stable — callers don't need to change when that arrives.
%% Port note: this Erlang implementation catches by explicit
%% class names (throw, error, exit) rather than the open
%% `Class:Reason` pattern. The wrappers below enumerate the three.
eval_pure(Fun, Arg) ->
try Fun(Arg) of
Result -> {ok, Result}
catch
throw:Reason -> {error, {throw, Reason}};
error:Reason -> {error, {error, Reason}};
exit:Reason -> {error, {exit, Reason}}
end.
eval_pure(Fun, Arg1, Arg2) ->
try Fun(Arg1, Arg2) of
Result -> {ok, Result}
catch
throw:Reason -> {error, {throw, Reason}};
error:Reason -> {error, {error, Reason}};
exit:Reason -> {error, {exit, Reason}}
end.