diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b4deda7..ece163d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next version +- Deprecated `Exn` module. Use the `Error` module instead. https://github.com/rescript-association/rescript-core/pull/230 + ## 1.5.2 - Remove aliases for runtime modules (`MapperRt`, `Internal`) and `Re`. https://github.com/rescript-association/rescript-core/pull/237 diff --git a/src/Core__BigInt.res b/src/Core__BigInt.res index 028349fb..e1fe4ea3 100644 --- a/src/Core__BigInt.res +++ b/src/Core__BigInt.res @@ -30,7 +30,7 @@ BigInt.fromStringExn("0o11") try { BigInt.fromStringExn("a") } catch { -| Exn.Error(_error) => 0n +| Error.Error(_error) => 0n } ``` */ diff --git a/src/Core__Error.mjs b/src/Core__Error.mjs index e5334cf8..886807e6 100644 --- a/src/Core__Error.mjs +++ b/src/Core__Error.mjs @@ -17,7 +17,10 @@ function panic(msg) { throw new Error("Panic! " + msg); } +var $$Error$1 = "JsError"; + export { + $$Error$1 as $$Error, $$EvalError , $$RangeError , $$ReferenceError , diff --git a/src/Core__Error.res b/src/Core__Error.res index 408b08ff..98bb964a 100644 --- a/src/Core__Error.res +++ b/src/Core__Error.res @@ -1,4 +1,7 @@ -type t = Js.Exn.t +type t = unknown + +@@warning("-38") /* unused extension constructor */ +exception Error = JsError external fromException: exn => option<t> = "?as_js_exn" external toException: t => exn = "%identity" @@ -10,6 +13,9 @@ external toException: t => exn = "%identity" @new external make: string => t = "Error" +external isCamlExceptionOrOpenVariant: 'a => bool = "?is_extension" +external anyToExnInternal: 'a => exn = "#wrap_exn" + module EvalError = { @new external make: string => t = "EvalError" } diff --git a/src/Core__Error.resi b/src/Core__Error.resi index 38b6a973..5aca8d49 100644 --- a/src/Core__Error.resi +++ b/src/Core__Error.resi @@ -5,7 +5,9 @@ See [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ */ /** Represents a JavaScript exception. */ -type t = Js.Exn.t +type t + +type exn += private Error(t) external fromException: exn => option<t> = "?as_js_exn" @@ -86,6 +88,35 @@ Console.log(error->Error.name) // Logs "Error" to the console, because this is a @new external make: string => t = "Error" +/** internal use only */ +external isCamlExceptionOrOpenVariant: 'a => bool = "?is_extension" + +/** +`anyToExnInternal(obj)` will take any value `obj` and wrap it +in a `Error.Error` if given value is not an exn already. If +`obj` is an exn, it will return `obj` without any changes. + +This function is mostly useful for cases where you want to unify a type of a value +that potentially is either exn, a JS error, or any other JS value really (e.g. for +a value passed to a Promise.catch callback) + +**IMPORTANT**: This is an internal API and may be changed / removed any time in the future. + +## Examples + +```rescript +switch Error.anyToExnInternal("test") { +| Error.Error(v) => + switch(Error.message(v)) { + | Some(_) => assert(false) + | None => Console.log2("We will land here", v) + } +| _ => assert(false) +} +``` +*/ +external anyToExnInternal: 'a => exn = "#wrap_exn" + module EvalError: { /** Creates a new `EvalError` with the provided `message`. diff --git a/src/Core__JSON.resi b/src/Core__JSON.resi index 9b5f714b..dcb7f1cd 100644 --- a/src/Core__JSON.resi +++ b/src/Core__JSON.resi @@ -33,7 +33,7 @@ try { let _ = JSON.parseExn("") // error } catch { -| Exn.Error(_) => Console.log("error") +| Error.Error(_) => Console.log("error") } let reviver = (_, value: JSON.t) => @@ -52,15 +52,15 @@ try { JSON.parseExn("", ~reviver)->Console.log // error } catch { -| Exn.Error(_) => Console.log("error") +| Error.Error(_) => Console.log("error") } ``` ## Exceptions -- Raises a SyntaxError (Exn.t) if the string isn't valid JSON. +- Raises a SyntaxError (Error.t) if the string isn't valid JSON. */ -@raises(Exn.t) +@raises(Error.t) @val external parseExn: (string, ~reviver: (string, t) => t=?) => t = "JSON.parse" @@ -89,7 +89,7 @@ try { JSON.parseExnWithReviver("", reviver)->Console.log // error } catch { -| Exn.Error(_) => Console.log("error") +| Error.Error(_) => Console.log("error") } ``` @@ -98,7 +98,7 @@ try { - Raises a SyntaxError if the string isn't valid JSON. */ @deprecated("Use `parseExn` with optional parameter instead") -@raises(Exn.t) +@raises(Error.t) @val external parseExnWithReviver: (string, (string, t) => t) => t = "JSON.parse" @@ -350,7 +350,7 @@ BigInt.fromInt(0)->JSON.stringifyAny - Raises a TypeError if the value contains circular references. - Raises a TypeError if the value contains `BigInt`s. */ -@raises(Exn.t) +@raises(Error.t) @val external stringifyAny: ('a, ~replacer: replacer=?, ~space: int=?) => option<string> = "JSON.stringify" @@ -391,7 +391,7 @@ BigInt.fromInt(0)->JSON.stringifyAny - Raises a TypeError if the value contains `BigInt`s. */ @deprecated("Use `stringifyAny` with optional parameter instead") -@raises(Exn.t) +@raises(Error.t) @val external stringifyAnyWithIndent: ('a, @as(json`null`) _, int) => option<string> = "JSON.stringify" diff --git a/src/Core__Promise.res b/src/Core__Promise.res index 8a4418d2..75e71c12 100644 --- a/src/Core__Promise.res +++ b/src/Core__Promise.res @@ -99,7 +99,7 @@ external _catch: (t<'a>, exn => t<'a>) => t<'a> = "catch" let catch = (promise: promise<'a>, callback: exn => promise<'a>): promise<'a> => { _catch(promise, err => { - callback(Js.Exn.anyToExnInternal(err)) + callback(Core__Error.anyToExnInternal(err)) }) } diff --git a/src/Core__Promise.resi b/src/Core__Promise.resi index 5468bf93..212368c3 100644 --- a/src/Core__Promise.resi +++ b/src/Core__Promise.resi @@ -126,8 +126,8 @@ reject(SomeError("this is an error")) ->catch(e => { let msg = switch(e) { | SomeError(msg) => "ReScript error occurred: " ++ msg - | Exn.Error(obj) => - switch Exn.message(obj) { + | Error.Error(obj) => + switch Error.message(obj) { | Some(msg) => "JS exception occurred: " ++ msg | None => "Some other JS value has been thrown" } diff --git a/src/RescriptCore.res b/src/RescriptCore.res index 2b52eb5f..b85988fe 100644 --- a/src/RescriptCore.res +++ b/src/RescriptCore.res @@ -94,7 +94,9 @@ async function main() { */ external import: 'a => promise<'a> = "#import" +@deprecated("Use `Error` module instead") module Exn = Js.Exn + module Option = Core__Option module List = Core__List module Result = Core__Result diff --git a/test/ErrorTests.mjs b/test/ErrorTests.mjs index dcced1d5..2865c24b 100644 --- a/test/ErrorTests.mjs +++ b/test/ErrorTests.mjs @@ -1,7 +1,7 @@ // Generated by ReScript, PLEASE EDIT WITH CARE import * as Test from "./Test.mjs"; -import * as Js_exn from "rescript/lib/es6/js_exn.js"; +import * as Core__Error from "../src/Core__Error.mjs"; import * as RescriptCore from "../src/RescriptCore.mjs"; import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; @@ -12,7 +12,7 @@ function panicTest() { } catch (raw_err){ var err = Caml_js_exceptions.internalToOCamlException(raw_err); - if (err.RE_EXN_ID === Js_exn.$$Error) { + if (err.RE_EXN_ID === Core__Error.$$Error) { caught = err._1.message; } else { throw err; diff --git a/test/ErrorTests.res b/test/ErrorTests.res index 07dcc078..21bd55e5 100644 --- a/test/ErrorTests.res +++ b/test/ErrorTests.res @@ -2,7 +2,7 @@ open RescriptCore let panicTest = () => { let caught = try panic("uh oh") catch { - | Exn.Error(err) => Error.message(err) + | Error.Error(err) => Error.message(err) } Test.run(__POS_OF__("Should resolve test"), caught, \"==", Some("Panic! uh oh")) diff --git a/test/IntTests.mjs b/test/IntTests.mjs index 593fb9eb..5fd72810 100644 --- a/test/IntTests.mjs +++ b/test/IntTests.mjs @@ -1,9 +1,9 @@ // Generated by ReScript, PLEASE EDIT WITH CARE import * as Test from "./Test.mjs"; -import * as Js_exn from "rescript/lib/es6/js_exn.js"; import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; import * as Core__Int from "../src/Core__Int.mjs"; +import * as Core__Error from "../src/Core__Error.mjs"; import * as PervasivesU from "rescript/lib/es6/pervasivesU.js"; import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; @@ -16,7 +16,7 @@ function $$catch(f) { } catch (raw_err){ var err = Caml_js_exceptions.internalToOCamlException(raw_err); - if (err.RE_EXN_ID === Js_exn.$$Error) { + if (err.RE_EXN_ID === Core__Error.$$Error) { return err._1; } throw err; diff --git a/test/IntTests.res b/test/IntTests.res index 4535b18e..95f5e9ce 100644 --- a/test/IntTests.res +++ b/test/IntTests.res @@ -7,7 +7,7 @@ let catch = f => let _ = f() failwith("no exception raised") } catch { - | Exn.Error(err) => err + | Error.Error(err) => err } Test.run(__POS_OF__("range - positive, increasing"), Int.range(3, 6), eq, [3, 4, 5]) diff --git a/test/PromiseTest.mjs b/test/PromiseTest.mjs index ffdb1df1..8a5468a8 100644 --- a/test/PromiseTest.mjs +++ b/test/PromiseTest.mjs @@ -1,14 +1,16 @@ // Generated by ReScript, PLEASE EDIT WITH CARE import * as Test from "./Test.mjs"; -import * as Js_exn from "rescript/lib/es6/js_exn.js"; import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; +import * as Core__Error from "../src/Core__Error.mjs"; import * as Core__Promise from "../src/Core__Promise.mjs"; import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; var TestError = /* @__PURE__ */Caml_exceptions.create("PromiseTest.TestError"); -var fail = Js_exn.raiseError; +function fail(msg) { + throw msg; +} var equal = Caml_obj.equal; @@ -161,7 +163,7 @@ function testExternalPromiseThrow() { return Core__Promise.$$catch(asyncParseFail().then(function (param) { return Promise.resolve(); }), (function (e) { - var success = e.RE_EXN_ID === Js_exn.$$Error ? Caml_obj.equal(e._1.name, "SyntaxError") : false; + var success = e.RE_EXN_ID === Core__Error.$$Error ? Caml_obj.equal(e._1.name, "SyntaxError") : false; Test.run([ [ "PromiseTest.res", @@ -199,9 +201,9 @@ function testExnThrow() { function testRaiseErrorThrow() { return Core__Promise.$$catch(Promise.resolve().then(function () { - return Js_exn.raiseError("Some JS error"); + throw new Error("Some JS error"); }), (function (e) { - var isTestErr = e.RE_EXN_ID === Js_exn.$$Error ? Caml_obj.equal(e._1.message, "Some JS error") : false; + var isTestErr = e.RE_EXN_ID === Core__Error.$$Error ? Caml_obj.equal(e._1.message, "Some JS error") : false; Test.run([ [ "PromiseTest.res", diff --git a/test/PromiseTest.res b/test/PromiseTest.res index 35197fea..8165fc60 100644 --- a/test/PromiseTest.res +++ b/test/PromiseTest.res @@ -3,7 +3,7 @@ open RescriptCore exception TestError(string) let fail = msg => { - Exn.raiseError(msg) + Error.raise(msg) } let equal = (a, b) => { @@ -132,7 +132,7 @@ module Catching = { ->then(_ => resolve()) // Since our asyncParse will fail anyways, we convert to promise<unit> for our catch later ->catch(e => { let success = switch e { - | Exn.Error(err) => Exn.name(err) == Some("SyntaxError") + | Error.Error(err) => Error.name(err) == Some("SyntaxError") | _ => false } @@ -166,7 +166,7 @@ module Catching = { open Promise let causeErr = () => { - Exn.raiseError("Some JS error") + Error.make("Some JS error")->Error.raise } resolve() @@ -175,7 +175,7 @@ module Catching = { }) ->catch(e => { let isTestErr = switch e { - | Exn.Error(err) => Exn.message(err) == Some("Some JS error") + | Error.Error(err) => Error.message(err) == Some("Some JS error") | _ => false } Test.run(__POS_OF__("Should be some JS error"), isTestErr, equal, true) diff --git a/test/intl/IntlTests.mjs b/test/intl/IntlTests.mjs index 6fcf5875..6929a88d 100644 --- a/test/intl/IntlTests.mjs +++ b/test/intl/IntlTests.mjs @@ -1,7 +1,7 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -import * as Js_exn from "rescript/lib/es6/js_exn.js"; import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as Core__Error from "../../src/Core__Error.mjs"; import * as Core__Option from "../../src/Core__Option.mjs"; import * as Intl__LocaleTest from "./Intl__LocaleTest.mjs"; import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; @@ -29,7 +29,7 @@ try { } catch (raw_e){ var e = Caml_js_exceptions.internalToOCamlException(raw_e); - if (e.RE_EXN_ID === Js_exn.$$Error) { + if (e.RE_EXN_ID === Core__Error.$$Error) { console.error(e._1); } else { throw e; @@ -46,7 +46,7 @@ try { } catch (raw_e$1){ var e$1 = Caml_js_exceptions.internalToOCamlException(raw_e$1); - if (e$1.RE_EXN_ID === Js_exn.$$Error) { + if (e$1.RE_EXN_ID === Core__Error.$$Error) { console.error(e$1._1); } else { throw e$1; @@ -59,7 +59,7 @@ try { } catch (raw_e$2){ var e$2 = Caml_js_exceptions.internalToOCamlException(raw_e$2); - if (e$2.RE_EXN_ID === Js_exn.$$Error) { + if (e$2.RE_EXN_ID === Core__Error.$$Error) { var e$3 = e$2._1; var message = Core__Option.map(e$3.message, (function (prim) { return prim.toLowerCase(); diff --git a/test/intl/IntlTests.res b/test/intl/IntlTests.res index d5fa1c6d..ad32f690 100644 --- a/test/intl/IntlTests.res +++ b/test/intl/IntlTests.res @@ -18,7 +18,7 @@ Intl.getCanonicalLocalesManyExn(["EN-US", "Fr"])->Console.log try { Intl.getCanonicalLocalesExn("bloop")->Console.log } catch { -| Exn.Error(e) => Console.error(e) +| Error.Error(e) => Console.error(e) } try { @@ -29,7 +29,7 @@ try { Intl.supportedValuesOfExn("timeZone")->Console.log Intl.supportedValuesOfExn("unit")->Console.log } catch { -| Exn.Error(e) => Console.error(e) +| Error.Error(e) => Console.error(e) } try { @@ -37,7 +37,7 @@ try { Console.error("Shouldn't have been hit") } catch { -| Exn.Error(e) => +| Error.Error(e) => switch Error.message(e)->Option.map(String.toLowerCase) { | Some("invalid key : someinvalidkey") => Console.log("Caught expected error") | message => {