diff --git a/CHANGELOG.md b/CHANGELOG.md index 23dc8533..c84920c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### API changes - Add `Math.Int.floor` and `Math.Int.random`, https://github.com/rescript-association/rescript-core/pull/156 +- Add `protect` https://github.com/rescript-association/rescript-core/pull/155 ### Documentation diff --git a/src/RescriptCore.res b/src/RescriptCore.res index 0cdb0025..174dde15 100644 --- a/src/RescriptCore.res +++ b/src/RescriptCore.res @@ -68,3 +68,29 @@ type undefined<+'a> = Js.undefined<'a> type nullable<+'a> = Js.nullable<'a> let panic = Core__Error.panic + +/** + `protect(~finally, f)` + + Tries to execute the function `f`, and ensures that `finally` will be called + whether `f` raises an exception or not. + + Any exception raised by `f` will be re-raised in order to be handled by the + user. If `finally` raises, then that exception will be emitted instead, and + any exception raised by `f` will go unnoticed. + + ```res example + try protect(~finally=() => Js.log("finally"), () => failwith("oh no!")) catch { + | Failure(err) => Js.log(err) + } + ``` +*/ +let protect = (~finally, f) => { + let result = try f() catch { + | exn => + finally() + raise(exn) + } + finally() + result +}