- Errors as Values are the Future: https://www.youtube.com/watch?v=T3pcb3o415c
Result Type
In gleam, when an operation can fail, it generally returns a Result.
It can be one of two things:
- An
Okwrapping the thing you want. - An
Errorwrapping the value that represents what went wrong.
type Result(t, e) {
Ok(t)
Error(e)
}
By treating errors as regular values, it allows the user to see that a function can fail just by looking at its return type:
fn() -> Result(a, b)
You can then pattern match on the value returned by the function:
case do_work() {
Ok(value) -> todo as "do something with the value"
Error(err) -> todo as "handle error"
}
Custom Error Types
You can define your custom error types at top level and return them from functions when necessary.
pub type AuthError {
/// Password doesnt match
WrongPassword
/// User not found in the Databse
NotFound
/// User account is inactive
AccountDisabled
}
pub fn verify_login(
ctx ctx: Context,
email email: String,
password password: String,
) -> Result(uuid.Uuid, AuthError) {
// Body of the function
}
The gleam/result module
The result.try function from the standard library takes a Result and a callback function describing what to do with the value in case of success. If the result is an Error, it will simply return it, without calling the callback function.
result.try(do_work(), fn(a) {
io.println(a)
Ok(Nil)
})
To avoid callback hell, result.try can be paired with use to keep your nesting minimal. If a function fail at any time during the execution, its error will be returned immediately.
use wibble <- result.try(failing_one())
use wobble <- result.try(failing_two())
do_work(wibble, wobble)