<@U5SUR9W2D> ``` val result: Try&lt;Unit&gt; = Tr...
# arrow
r
@veiset
Copy code
val result: Try<Unit> = Try {  accessChecker.loggedInUserHasAccess() }.flatMap { 
  if (it) Try.just(Unit) else Try.raise(FeatureAccessDeniedException("No access for feature"))
}
Copy code
val result: Try[Unit] = ForTry extensions {
  bindingCatch {
     val hasAccess = Try {  accessChecker.loggedInUserHasAccess() }.bind()
     if (hasAccess) just(Unit).bind()
     else raiseError(FeatureAccessDeniedException("No access for feature")).bind()
  }.fix()
}
or even better since this kind of modeling is not particular to
Try
but to any data type that can perform error handling:
Copy code
fun <F> MonadError<F>.checkAccess(): Kind<F, Unit> =
  bindingCatch {
     val hasAccess = catch {  accessChecker.loggedInUserHasAccess() }.bind()
     if (hasAccess) just(Unit).bind()
     else raiseError(FeatureAccessDeniedException("No access for feature")).bind()
  }  

Try.monadError().checkAccess().fix() // Try<Unit>
Either.monadError<FeatureAccessDeniedException>().checkAccess().fix() // Either<FeatureAccessDeniedException, Unit>
IO.monadError().checkAccess().fix() // IO<Unit>
DeferredK.monadError().checkAccess().fix() // Deferred<Unit>
ObservableK.monadError().checkAccess().fix() // Observable<Unit>
...
This is all assuming
loggedInUserHasAccess
may throw exceptions otherwise is simpler.