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..c9fb3df163 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,20 @@ 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"];