From 29393b884e889c5c2d33b3894d5a3653a6e19f27 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 7 Dec 2025 16:25:30 +0000 Subject: [PATCH 1/2] Port :erlang.exit/1 to JS --- assets/js/erlang/erlang.mjs | 8 +++++ assets/js/errors/exit_error.mjs | 11 +++++++ .../ex_js_consistency/erlang/erlang_test.exs | 29 +++++++++++++++++++ test/javascript/erlang/erlang_test.mjs | 21 ++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 assets/js/errors/exit_error.mjs diff --git a/assets/js/erlang/erlang.mjs b/assets/js/erlang/erlang.mjs index 4530d1a45a..8423a89f21 100644 --- a/assets/js/erlang/erlang.mjs +++ b/assets/js/erlang/erlang.mjs @@ -2,6 +2,7 @@ import Bitstring from "../bitstring.mjs"; import HologramBoxedError from "../errors/boxed_error.mjs"; +import HologramExitError from "../errors/exit_error.mjs"; import HologramInterpreterError from "../errors/interpreter_error.mjs"; import Interpreter from "../interpreter.mjs"; import Type from "../type.mjs"; @@ -584,6 +585,13 @@ const Erlang = { // End error/2 // Deps: [] + // Start exit/1 + "exit/1": (reason) => { + throw new HologramExitError(reason); + }, + // End exit/1 + // Deps: [] + // Start float/1 "float/1": (number) => { if (Type.isInteger(number)) { diff --git a/assets/js/errors/exit_error.mjs b/assets/js/errors/exit_error.mjs new file mode 100644 index 0000000000..76681bbecb --- /dev/null +++ b/assets/js/errors/exit_error.mjs @@ -0,0 +1,11 @@ +"use strict"; + +export default class HologramExitError extends Error { + constructor(reason) { + super(""); + + this.name = "HologramExitError"; + this.reason = reason; + this.message = `exit with reason: ${JSON.stringify(reason)}`; + } +} diff --git a/test/elixir/hologram/ex_js_consistency/erlang/erlang_test.exs b/test/elixir/hologram/ex_js_consistency/erlang/erlang_test.exs index 635145c6c5..7aba4d5966 100644 --- a/test/elixir/hologram/ex_js_consistency/erlang/erlang_test.exs +++ b/test/elixir/hologram/ex_js_consistency/erlang/erlang_test.exs @@ -1907,6 +1907,35 @@ defmodule Hologram.ExJsConsistency.Erlang.ErlangTest do end end + describe "exit/1" do + test "raises with atom reason" do + try do + :erlang.exit(:normal) + flunk("expected exit to be raised") + catch + :exit, reason -> assert reason == :normal + end + end + + test "raises with tuple reason" do + try do + :erlang.exit({:error, :reason}) + flunk("expected exit to be raised") + catch + :exit, reason -> assert reason == {:error, :reason} + end + end + + test "raises with integer reason" do + try do + :erlang.exit(1) + flunk("expected exit to be raised") + catch + :exit, reason -> assert reason == 1 + end + end + end + describe "float/1" do test "converts integer to float" do assert :erlang.float(1) == 1.0 diff --git a/test/javascript/erlang/erlang_test.mjs b/test/javascript/erlang/erlang_test.mjs index ba4c1dd941..985421decf 100644 --- a/test/javascript/erlang/erlang_test.mjs +++ b/test/javascript/erlang/erlang_test.mjs @@ -12,6 +12,7 @@ import { import Bitstring from "../../../assets/js/bitstring.mjs"; import Erlang from "../../../assets/js/erlang/erlang.mjs"; +import HologramExitError from "../../../assets/js/errors/exit_error.mjs"; import HologramInterpreterError from "../../../assets/js/errors/interpreter_error.mjs"; import Interpreter from "../../../assets/js/interpreter.mjs"; import Type from "../../../assets/js/type.mjs"; @@ -2628,6 +2629,26 @@ describe("Erlang", () => { assertBoxedError(() => error(reason, args), "MyError", "my message"); }); + it("exit/1", () => { + const exit = Erlang["exit/1"]; + const reason = Type.atom("normal"); + + assert.throws( + () => exit(reason), + HologramExitError, + ); + }); + + it("exit/1 with tuple reason", () => { + const exit = Erlang["exit/1"]; + const reason = Type.tuple([Type.atom("error"), Type.atom("reason")]); + + assert.throws( + () => exit(reason), + HologramExitError, + ); + }); + describe("float/1", () => { const float = Erlang["float/1"]; From 221fcd5055d07dc0f2bed93049cfb1ffc36ec3ce Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Sun, 7 Dec 2025 17:17:56 +0000 Subject: [PATCH 2/2] Fix: Format erlang_test.mjs --- test/javascript/erlang/erlang_test.mjs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/javascript/erlang/erlang_test.mjs b/test/javascript/erlang/erlang_test.mjs index 985421decf..c9fb3df163 100644 --- a/test/javascript/erlang/erlang_test.mjs +++ b/test/javascript/erlang/erlang_test.mjs @@ -2633,20 +2633,14 @@ describe("Erlang", () => { const exit = Erlang["exit/1"]; const reason = Type.atom("normal"); - assert.throws( - () => exit(reason), - HologramExitError, - ); + assert.throws(() => exit(reason), HologramExitError); }); it("exit/1 with tuple reason", () => { const exit = Erlang["exit/1"]; const reason = Type.tuple([Type.atom("error"), Type.atom("reason")]); - assert.throws( - () => exit(reason), - HologramExitError, - ); + assert.throws(() => exit(reason), HologramExitError); }); describe("float/1", () => {