The unfortunately missing part of exceptions (in mainstream languages) is that they handle this invisibly. Figuring out, at compile time, what sort of exceptions can appear inside a given function is not obvious.
That's the big payoff of ROP: you can look at any function signature and immediately know what sort of errors can come out of it.
Mitigating the downside of ROP (boilerplate) can be done to various extents, depending on the language. Haskell has do-notation. In F#, using the result computation expression [0] can make your code extremely clean:
type LoginError = InvalidUser | InvalidPwd | Unauthorized of AuthError
let login (username : string) (password : string) : Result<AuthToken, LoginError> =
result {
// requireSome unwraps a Some value or gives the specified error if None
let! user = username |> tryGetUser |> Result.requireSome InvalidUser
// requireTrue gives the specified error if false
do! user |> isPwdValid password |> Result.requireTrue InvalidPwd
// Error value is wrapped/transformed (Unauthorized has signature AuthError -> LoginError)
do! user |> authorize |> Result.mapError Unauthorized
return user |> createAuthToken
}
Could we do the reverse, i.e. mitigate the downside of exceptions? Is there a linter, code analyzer, or some other compile-time tool that can integrate with a Java IDE and automatically display the uncaught exceptions that might be thrown by a given line of code?[0] https://demystifyfp.gitbook.io/fstoolkit-errorhandling/fstoo...