Skip to content

Commit ed0627e

Browse files
committed
Use RescriptError class for exceptions
1 parent 143486b commit ed0627e

File tree

4 files changed

+36
-45
lines changed

4 files changed

+36
-45
lines changed

jscomp/core/js_dump.ml

+9-29
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,7 @@ type cxt = Ext_pp_scope.t
9797
let semi f = P.string f L.semi
9898
let comma f = P.string f L.comma
9999

100-
let new_error name cause =
101-
E.new_ (E.js_global Js_dump_lit.error) [ name; cause ]
102-
103-
let exn_block_as_obj ~(stack : bool) (el : J.expression list) (ext : J.tag_info)
100+
let exn_block_as_obj ~(is_exception : bool) (el : J.expression list) (ext : J.tag_info)
104101
: J.expression =
105102
let field_name =
106103
match ext with
@@ -111,29 +108,18 @@ let exn_block_as_obj ~(stack : bool) (el : J.expression list) (ext : J.tag_info)
111108
fun i -> match i with 0 -> Literals.exception_id | i -> ss.(i - 1))
112109
| _ -> assert false
113110
in
114-
let cause =
111+
let extension =
115112
{
116113
J.expression_desc =
117114
Object (List.mapi (fun i e -> (Js_op.Lit (field_name i), e)) el);
118115
comment = None;
119116
}
120117
in
121-
if stack then
122-
new_error (List.hd el)
123-
{
124-
J.expression_desc = Object [ (Lit Js_dump_lit.cause, cause) ];
125-
comment = None;
126-
}
127-
else cause
128-
129-
let exn_ref_as_obj e : J.expression =
130-
let cause = { J.expression_desc = e; comment = None; } in
131-
new_error
132-
(E.record_access cause Js_dump_lit.exception_id 0l)
133-
{
134-
J.expression_desc = Object [ (Lit Js_dump_lit.cause, cause) ];
135-
comment = None;
136-
}
118+
if is_exception then
119+
match el with
120+
| [extension_id] -> E.runtime_call Js_runtime_modules.caml_js_exceptions "internalMakeExn" [extension_id]
121+
| _ -> E.runtime_call Js_runtime_modules.caml_js_exceptions "internalFromExtension" [extension]
122+
else extension
137123

138124
let rec iter_lst cxt (f : P.t) ls element inter =
139125
match ls with
@@ -774,8 +760,8 @@ and expression_desc cxt ~(level : int) f x : cxt =
774760
(Lit Literals.polyvar_value, value);
775761
])
776762
| _ -> assert false)
777-
| Caml_block (el, _, _, ((Blk_extension _ | Blk_record_ext _) as ext)) ->
778-
expression cxt ~level f (exn_block_as_obj ~stack:false el ext)
763+
| Caml_block (el, _, _, ((Blk_extension { is_exception } | Blk_record_ext { is_exception}) as ext)) ->
764+
expression cxt ~level f (exn_block_as_obj ~is_exception el ext)
779765
| Caml_block (el, _, tag, Blk_record_inlined p) ->
780766
let untagged = Ast_untagged_variants.process_untagged p.attrs in
781767
let objs =
@@ -1234,12 +1220,6 @@ and statement_desc top cxt f (s : J.statement_desc) : cxt =
12341220
P.newline f;
12351221
statements false cxt f def))
12361222
| Throw e ->
1237-
let e =
1238-
match e.expression_desc with
1239-
| Caml_block (el, _, _, ((Blk_extension _ | Blk_record_ext _) as ext)) ->
1240-
{ e with expression_desc = (exn_block_as_obj ~stack:true el ext).expression_desc }
1241-
| exp -> { e with expression_desc = (exn_ref_as_obj exp).expression_desc }
1242-
in
12431223
P.string f L.throw;
12441224
P.space f;
12451225
P.group f 0 (fun _ ->

jscomp/core/lam_compile_primitive.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
7979
| Pcreate_extension s -> E.make_exception s
8080
| Pwrap_exn ->
8181
E.runtime_call Js_runtime_modules.caml_js_exceptions
82-
"internalToOCamlException" args
82+
"internalAnyToExn" args
8383
| Praw_js_code { code; code_info } -> E.raw_js_code code_info code
8484
(* FIXME: save one allocation
8585
trim can not be done before syntax checking

jscomp/runtime/caml_exceptions.res

+2-6
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,8 @@ let create = (str: string): string => {
8989
9090
This is not a problem in `try .. with` since the logic above is not expressible, see more design in [destruct_exn.md]
9191
*/
92-
let is_extension = (type a, e: a): bool =>
93-
if Js.testAny(e) {
94-
false
95-
} else {
96-
Js.typeof((Obj.magic(e): t).id) == "string"
97-
}
92+
let is_extension = (any: 'a): bool =>
93+
Obj.magic(any) && Js.typeof((Obj.magic(any): t).id) === "string"
9894

9995
/** FIXME: remove the trailing `/` */
10096
let exn_slot_name = (x: t): string => x.id

jscomp/runtime/caml_js_exceptions.res

+24-9
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,32 @@
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2424

2525
exception Error = JsError
26-
type js_error = {cause: exn}
27-
/**
28-
This function has to be in this module Since
29-
[Error] is defined here
30-
*/
31-
let internalToOCamlException = (e: unknown) =>
32-
if Caml_exceptions.is_extension((Obj.magic(e): js_error).cause) {
33-
(Obj.magic(e): js_error).cause
26+
27+
let internalAnyToExn = (any: 'a): exn =>
28+
if Obj.magic(any) && Js.typeof(Obj.magic(any)["RE_EXN_ID"]) === "string" {
29+
any->Obj.magic
3430
} else {
35-
JsError(e)
31+
{
32+
"RE_EXN_ID": "JsError",
33+
"_1": any,
34+
}->Obj.magic
35+
}
36+
37+
%%raw(`class RescriptError extends Error {
38+
constructor(message) {
39+
super(message);
40+
this.RE_EXN_ID = message;
3641
}
42+
}`)
43+
44+
@new
45+
external internalMakeExn: string => exn = "RescriptError"
46+
// Reassign it here from external to let, since RescriptError is not exported
47+
let internalMakeExn = internalMakeExn
48+
49+
let internalFromExtension = (_ext: 'a): exn => {
50+
%raw(`Object.assign(new RescriptError(_ext.RE_EXN_ID), _ext)`)
51+
}
3752

3853
let as_js_exn = exn =>
3954
switch exn {

0 commit comments

Comments
 (0)