I tried using pog.transaction and it kind of confused me that the error type for the transaction is stringly typed. Here's my code:
type CreateError {
UsernameAlreadyInUse
WeakPassword
CannotCreateUser
}
fn create_user(db, username, password) -> Result(_, CreateError) {
use validated <- result.try(validate_password(password))
use hashes <- result.try(hash_password(validated))
case try_create_user(db, username, hashes) {
Ok(_) -> Ok(...)
Error(pog.TransactionRolledBack("UsernameAlreadyInUse")) ->
Error(UsernameAlreadyInUse)
Error(pog.TransactionRolledBack("CannotCreateUser") ->
Error(CannotCreateUser)
Error(pog.TransactionRolledBack(_)) ->
panic as "unexpected rollback reason"
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here I'm turning the string back in an error
}
}
fn try_create_user(db, username, hashes) {
use db <- pog.transaction(db)
case sql.create_user(username, hashes.encoded_hash) {
Error(pog.ConstraintViolation(..)) -> Error("UsernameAlreadyInUse")
Error(_) -> Error("CannotCreateUser")
// ^^^^^^^^^^^^^^^^^^^^^^^^^ Error here must be a string!
Ok(_) -> todo as "other queries in the same transaction..."
}
}
create_user's result is later turned into a response I send back to the client. However, working with a transaction like this doesn't really feel great. Am I going about this completely wrong? Is this something others have brought up?