@@ -63,10 +63,44 @@ let create (str : string) : Caml_builtin_exceptions.exception_block =
63
63
v
64
64
65
65
external isUndefined : 'a -> bool = " #is_undef"
66
- (* * It could be either customized exception or built in exception *)
67
- let isCamlException e =
66
+
67
+
68
+ (* *
69
+ This function should never throw
70
+ It could be either customized exception or built in exception
71
+ Note due to that in OCaml extensible variants have the same
72
+ runtime representation as exception, so we can not
73
+ really tell the difference.
74
+
75
+ However, if we make a false alarm, classified extensible variant
76
+ as exception, it will be OKAY for nested pattern match
77
+
78
+ {[
79
+ match toExn x : exn option with
80
+ | Some _
81
+ -> Js.log "Could be an OCaml exception or an open variant"
82
+ (* If it is an Open variant, it will never pattern match,
83
+ This is Okay, since exception could never have exhaustive pattern match
84
+
85
+ *)
86
+ | None -> Js.log "Not an OCaml exception for sure"
87
+ ]}
88
+
89
+ However, there is still something wrong, since if user write such code
90
+ {[
91
+ match toExn x with
92
+ | Some _ -> (* assert it is indeed an exception *)
93
+ (* This assertion is wrong, since it could be an open variant *)
94
+ | None -> (* assert it is not an exception *)
95
+ ]}
96
+
97
+ This is not a problem in `try .. with` since the logic above is not expressible, see more design in [destruct_exn.md]
98
+ *)
99
+ let isCamlExceptionOrOpenVariant e =
68
100
Obj. tag e = object_tag (* nullary exception *)
69
101
||
70
102
let slot = Obj. field e 0 in
71
103
not (isUndefined slot) &&
72
104
(Obj. tag slot = object_tag)
105
+
106
+
0 commit comments