Skip to content

Commit 249cb40

Browse files
authored
Add optional message argument to Result.getOrThrow and improve default error message (#7630)
* Add optional message argument to Result.getOrThrow and improve default error message * Add CHANGELOG entry * Use JsError.panic instead of deprecated Error.panic for Option.getOrThrow * Update completions * Note breaking change in CHANGELOG
1 parent 5109bb0 commit 249cb40

File tree

10 files changed

+55
-33
lines changed

10 files changed

+55
-33
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
1313
# 12.0.0-beta.3 (Unreleased)
1414

15+
#### :boom: Breaking Change
16+
17+
- `Result.getOrThrow` now throws a JS error instead of a `Not_found` ReScript exception. https://github.com/rescript-lang/rescript/pull/7630
18+
19+
#### :rocket: New Feature
20+
21+
- Add optional `message` argument to `Result.getOrThrow` and improve default error message. https://github.com/rescript-lang/rescript/pull/7630
22+
1523
#### :nail_care: Polish
1624

1725
- Configuration fields `bs-dependencies`, `bs-dev-dependencies` and `bsc-flags` are now deprecated in favor of `dependencies`, `dev-dependencies` and `compiler-flags`. https://github.com/rescript-lang/rescript/pull/7658

lib/es6/Stdlib_Option.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22

3-
import * as Stdlib_Error from "./Stdlib_Error.js";
3+
import * as Stdlib_JsError from "./Stdlib_JsError.js";
44
import * as Primitive_option from "./Primitive_option.js";
55

66
function filter(opt, p) {
@@ -21,7 +21,7 @@ function getOrThrow(x, message) {
2121
if (x !== undefined) {
2222
return Primitive_option.valFromOption(x);
2323
} else {
24-
return Stdlib_Error.panic(message !== undefined ? message : "Option.getOrThrow called for None value");
24+
return Stdlib_JsError.panic(message !== undefined ? message : "Option.getOrThrow called for None value");
2525
}
2626
}
2727

lib/es6/Stdlib_Result.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11

22

3+
import * as Stdlib_JsError from "./Stdlib_JsError.js";
34

4-
function getOrThrow(x) {
5+
function getOrThrow(x, message) {
56
if (x.TAG === "Ok") {
67
return x._0;
8+
} else {
9+
return Stdlib_JsError.panic(message !== undefined ? message : "Result.getOrThrow called for Error value");
710
}
8-
throw {
9-
RE_EXN_ID: "Not_found",
10-
Error: new Error()
11-
};
1211
}
1312

1413
function mapOr(opt, $$default, f) {

lib/js/Stdlib_Option.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
let Stdlib_Error = require("./Stdlib_Error.js");
3+
let Stdlib_JsError = require("./Stdlib_JsError.js");
44
let Primitive_option = require("./Primitive_option.js");
55

66
function filter(opt, p) {
@@ -21,7 +21,7 @@ function getOrThrow(x, message) {
2121
if (x !== undefined) {
2222
return Primitive_option.valFromOption(x);
2323
} else {
24-
return Stdlib_Error.panic(message !== undefined ? message : "Option.getOrThrow called for None value");
24+
return Stdlib_JsError.panic(message !== undefined ? message : "Option.getOrThrow called for None value");
2525
}
2626
}
2727

lib/js/Stdlib_Result.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
'use strict';
22

3+
let Stdlib_JsError = require("./Stdlib_JsError.js");
34

4-
function getOrThrow(x) {
5+
function getOrThrow(x, message) {
56
if (x.TAG === "Ok") {
67
return x._0;
8+
} else {
9+
return Stdlib_JsError.panic(message !== undefined ? message : "Result.getOrThrow called for Error value");
710
}
8-
throw {
9-
RE_EXN_ID: "Not_found",
10-
Error: new Error()
11-
};
1211
}
1312

1413
function mapOr(opt, $$default, f) {

runtime/Stdlib_Option.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let getOrThrow = (x, ~message=?) =>
3939
switch x {
4040
| Some(x) => x
4141
| None =>
42-
Stdlib_Error.panic(
42+
Stdlib_JsError.panic(
4343
switch message {
4444
| None => "Option.getOrThrow called for None value"
4545
| Some(message) => message

runtime/Stdlib_Option.resi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Option.forEach(None, x => Console.log(x)) // returns ()
7171
let forEach: (option<'a>, 'a => unit) => unit
7272

7373
/**
74-
`getExn(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise raises an exception with the message provided, or a generic message if no message was provided.
74+
`getExn(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.
7575
7676
```rescript
7777
Option.getExn(Some(3)) == 3
@@ -82,20 +82,20 @@ switch Option.getExn(None) {
8282
}
8383
8484
switch Option.getExn(None, ~message="was None!") {
85-
| exception _ => assert(true) // Raises an Error with the message "was None!"
85+
| exception _ => assert(true) // Throws a JsError with the message "was None!"
8686
| _ => assert(false)
8787
}
8888
```
8989
9090
## Exceptions
9191
92-
- Raises an error if `opt` is `None`
92+
- Throws an error if `opt` is `None`
9393
*/
9494
@deprecated("Use `getOrThrow` instead")
9595
let getExn: (option<'a>, ~message: string=?) => 'a
9696

9797
/**
98-
`getOrThrow(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise raises an exception with the message provided, or a generic message if no message was provided.
98+
`getOrThrow(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.
9999
100100
```rescript
101101
Option.getOrThrow(Some(3)) == 3
@@ -106,14 +106,14 @@ switch Option.getOrThrow(None) {
106106
}
107107
108108
switch Option.getOrThrow(None, ~message="was None!") {
109-
| exception _ => assert(true) // Raises an Error with the message "was None!"
109+
| exception _ => assert(true) // Throws a JsError with the message "was None!"
110110
| _ => assert(false)
111111
}
112112
```
113113
114114
## Exceptions
115115
116-
- Raises an error if `opt` is `None`
116+
- Throws an error if `opt` is `None`
117117
*/
118118
let getOrThrow: (option<'a>, ~message: string=?) => 'a
119119

runtime/Stdlib_Result.res

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2424
type t<'res, 'err> = result<'res, 'err> = Ok('res) | Error('err)
2525

26-
let getOrThrow = x =>
26+
let getOrThrow = (x, ~message=?) =>
2727
switch x {
2828
| Ok(x) => x
29-
| Error(_) => throw(Not_found)
29+
| Error(_) =>
30+
Stdlib_JsError.panic(
31+
switch message {
32+
| None => "Result.getOrThrow called for Error value"
33+
| Some(message) => message
34+
},
35+
)
3036
}
3137

3238
let getExn = getOrThrow

runtime/Stdlib_Result.resi

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,43 @@ query operation:
4848
type t<'res, 'err> = result<'res, 'err> = Ok('res) | Error('err)
4949

5050
/**
51-
`getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception
51+
`getExn(res, ~message=?)` returns `n` if `res` is `Ok(n)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.
5252
5353
```res example
5454
Result.getExn(Result.Ok(42)) == 42
5555
5656
switch Result.getExn(Error("Invalid data")) {
57-
| exception Not_found => assert(true)
57+
| exception _ => assert(true)
58+
| _ => assert(false)
59+
}
60+
61+
switch Result.getExn(Error("Invalid data"), ~message="was Error!") {
62+
| exception _ => assert(true) // Throws a JsError with the message "was Error!"
5863
| _ => assert(false)
5964
}
6065
```
6166
*/
6267
@deprecated("Use 'getOrThrow' instead")
63-
let getExn: result<'a, 'b> => 'a
68+
let getExn: (result<'a, 'b>, ~message: string=?) => 'a
6469

6570
/**
66-
`getOrThrow(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception
71+
`getOrThrow(res, ~message=?)` returns `n` if `res` is `Ok(n)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.
6772
6873
```res example
6974
Result.getOrThrow(Result.Ok(42)) == 42
7075
7176
switch Result.getOrThrow(Error("Invalid data")) {
72-
| exception Not_found => assert(true)
77+
| exception _ => assert(true)
78+
| _ => assert(false)
79+
}
80+
81+
switch Result.getOrThrow(Error("Invalid data"), ~message="was Error!") {
82+
| exception _ => assert(true) // Throws a JsError with the message "was Error!"
7383
| _ => assert(false)
7484
}
7585
```
7686
*/
77-
let getOrThrow: result<'a, 'b> => 'a
87+
let getOrThrow: (result<'a, 'b>, ~message: string=?) => 'a
7888

7989
/**
8090
`mapOr(res, default, f)`: When res is `Ok(n)`, returns `f(n)`, otherwise `default`.

tests/analysis_tests/tests/src/expected/Completion.res.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,14 +2597,14 @@ Path g
25972597
"label": "Result.getExn",
25982598
"kind": 12,
25992599
"tags": [1],
2600-
"detail": "result<'a, 'b> => 'a",
2601-
"documentation": {"kind": "markdown", "value": "Deprecated: Use 'getOrThrow' instead\n\n\n `getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n ```res example\n Result.getExn(Result.Ok(42)) == 42\n \n switch Result.getExn(Error(\"Invalid data\")) {\n | exception Not_found => assert(true)\n | _ => assert(false)\n }\n ```\n"}
2600+
"detail": "(result<'a, 'b>, ~message: string=?) => 'a",
2601+
"documentation": {"kind": "markdown", "value": "Deprecated: Use 'getOrThrow' instead\n\n\n `getExn(res, ~message=?)` returns `n` if `res` is `Ok(n)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.\n\n ```res example\n Result.getExn(Result.Ok(42)) == 42\n \n switch Result.getExn(Error(\"Invalid data\")) {\n | exception _ => assert(true)\n | _ => assert(false)\n }\n\n switch Result.getExn(Error(\"Invalid data\"), ~message=\"was Error!\") {\n | exception _ => assert(true) // Throws a JsError with the message \"was Error!\"\n | _ => assert(false)\n }\n ```\n"}
26022602
}, {
26032603
"label": "Result.getOrThrow",
26042604
"kind": 12,
26052605
"tags": [],
2606-
"detail": "result<'a, 'b> => 'a",
2607-
"documentation": {"kind": "markdown", "value": "\n `getOrThrow(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n ```res example\n Result.getOrThrow(Result.Ok(42)) == 42\n \n switch Result.getOrThrow(Error(\"Invalid data\")) {\n | exception Not_found => assert(true)\n | _ => assert(false)\n }\n ```\n"}
2606+
"detail": "(result<'a, 'b>, ~message: string=?) => 'a",
2607+
"documentation": {"kind": "markdown", "value": "\n `getOrThrow(res, ~message=?)` returns `n` if `res` is `Ok(n)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.\n\n ```res example\n Result.getOrThrow(Result.Ok(42)) == 42\n \n switch Result.getOrThrow(Error(\"Invalid data\")) {\n | exception _ => assert(true)\n | _ => assert(false)\n }\n\n switch Result.getOrThrow(Error(\"Invalid data\"), ~message=\"was Error!\") {\n | exception _ => assert(true) // Throws a JsError with the message \"was Error!\"\n | _ => assert(false)\n }\n ```\n"}
26082608
}, {
26092609
"label": "Result.getOr",
26102610
"kind": 12,

0 commit comments

Comments
 (0)