wip: currently rewriting the project as a full stack application tangled.org/kacaii.dev/sigo
gleam

:recycle: extract remaining db error handling to its own function

+95 -103
+77 -83
src/app/domain/admin/admin_update_user.gleam
··· 55 55 } 56 56 } 57 57 58 + type RequestBody { 59 + RequestBody( 60 + full_name: String, 61 + email: String, 62 + user_role: role.Role, 63 + registration: String, 64 + is_active: Bool, 65 + ) 66 + } 67 + 68 + fn body_decoder() -> decode.Decoder(RequestBody) { 69 + use full_name <- decode.field("full_name", decode.string) 70 + use email <- decode.field("email", decode.string) 71 + use user_role <- decode.field("user_role", role.decoder()) 72 + use registration <- decode.field("registration", decode.string) 73 + use is_active <- decode.field("is_active", decode.bool) 74 + 75 + decode.success(RequestBody( 76 + full_name:, 77 + email:, 78 + user_role:, 79 + registration:, 80 + is_active:, 81 + )) 82 + } 83 + 58 84 type AdminUpdateUserError { 59 85 /// Failed to access the DataBase 60 86 DataBase(pog.QueryError) ··· 63 89 /// Authentication / Authorization failed 64 90 AccessControl(user.AccessControlError) 65 91 /// User not found in the DataBase 66 - UserNotFound(uuid.Uuid) 92 + NotFound(uuid.Uuid) 67 93 } 68 94 69 95 fn handle_error( ··· 76 102 77 103 InvalidUuid(id) -> wisp.bad_request("Usuário possui Uuid inválido: " <> id) 78 104 79 - UserNotFound(id) -> { 80 - let body = "Usuário não encontrado: " <> uuid.to_string(id) 81 - 82 - body 83 - |> wisp.Text 105 + NotFound(id) -> 106 + wisp.Text("Usuário não encontrado: " <> uuid.to_string(id)) 84 107 |> wisp.set_body(wisp.not_found(), _) 85 - } 86 108 87 - DataBase(err) -> { 88 - case err { 89 - pog.ConstraintViolated(_, _, constraint: "user_account_email_key") -> { 90 - let body = "Email já está sendo utilizado: " <> body.email 109 + DataBase(err) -> handle_database_error(err, body) 110 + } 111 + } 91 112 92 - body 93 - |> wisp.Text 94 - |> wisp.set_body(wisp.response(409), _) 95 - } 113 + fn handle_database_error( 114 + err: pog.QueryError, 115 + body: RequestBody, 116 + ) -> wisp.Response { 117 + case err { 118 + pog.ConstraintViolated(_, _, constraint: "user_account_email_key") -> 119 + wisp.Text("Email já está sendo utilizado: " <> body.email) 120 + |> wisp.set_body(wisp.response(409), _) 96 121 97 - pog.ConstraintViolated( 98 - _, 99 - _, 100 - constraint: "user_account_registration_key", 101 - ) -> { 102 - let body = "Matrícula já está sendo utilizada: " <> body.registration 122 + pog.ConstraintViolated(_, _, constraint: "user_account_registration_key") -> 123 + wisp.Text("Matrícula já está sendo utilizada: " <> body.registration) 124 + |> wisp.set_body(wisp.response(409), _) 103 125 104 - body 105 - |> wisp.Text 106 - |> wisp.set_body(wisp.response(409), _) 107 - } 126 + pog.ConstraintViolated(_, _, constraint: "user_account_phone_key") -> { 127 + "Telefone já cadastrado. Por favor, utilize um diferente" 128 + |> wisp.Text 129 + |> wisp.set_body(wisp.response(409), _) 130 + } 108 131 109 - err -> web.handle_database_error(err) 110 - } 111 - } 132 + err -> web.handle_database_error(err) 112 133 } 113 134 } 114 135 ··· 146 167 |> result.map_error(DataBase), 147 168 ) 148 169 149 - case list.first(returned.rows) { 150 - Error(_) -> Error(UserNotFound(user_uuid)) 151 - Ok(row) -> { 152 - let user_role = case row.user_role { 153 - sql.Admin -> role.Admin 154 - sql.Analyst -> role.Analyst 155 - sql.Captain -> role.Captain 156 - sql.Developer -> role.Developer 157 - sql.Firefighter -> role.Firefighter 158 - sql.Sargeant -> role.Sargeant 159 - } 160 - 161 - let updated_at_json = 162 - json.float( 163 - row.updated_at 164 - |> timestamp.to_unix_seconds(), 165 - ) 170 + use row <- result.map( 171 + list.first(returned.rows) 172 + |> result.replace_error(NotFound(user_uuid)), 173 + ) 166 174 167 - json.object([ 168 - #("id", json.string(uuid.to_string(row.id))), 169 - #("full_name", json.string(row.full_name)), 170 - #("email", json.string(row.email)), 171 - #("user_role", json.string(role.to_string_pt_br(user_role))), 172 - #("registration", json.string(row.registration)), 173 - #("updated_at", updated_at_json), 174 - #("is_active", json.bool(row.is_active)), 175 - ]) 176 - |> json.to_string 177 - |> Ok 178 - } 175 + let user_role = case row.user_role { 176 + sql.Admin -> role.Admin 177 + sql.Analyst -> role.Analyst 178 + sql.Captain -> role.Captain 179 + sql.Developer -> role.Developer 180 + sql.Firefighter -> role.Firefighter 181 + sql.Sargeant -> role.Sargeant 179 182 } 183 + 184 + let updated_at_json = 185 + json.float( 186 + row.updated_at 187 + |> timestamp.to_unix_seconds(), 188 + ) 189 + 190 + json.object([ 191 + #("id", json.string(uuid.to_string(row.id))), 192 + #("full_name", json.string(row.full_name)), 193 + #("email", json.string(row.email)), 194 + #("user_role", json.string(role.to_string_pt_br(user_role))), 195 + #("registration", json.string(row.registration)), 196 + #("updated_at", updated_at_json), 197 + #("is_active", json.bool(row.is_active)), 198 + ]) 199 + |> json.to_string 180 200 } 181 201 182 202 fn role_to_enum(role: role.Role) { ··· 189 209 role.Sargeant -> sql.Sargeant 190 210 } 191 211 } 192 - 193 - fn body_decoder() { 194 - use full_name <- decode.field("full_name", decode.string) 195 - use email <- decode.field("email", decode.string) 196 - use user_role <- decode.field("user_role", role.decoder()) 197 - use registration <- decode.field("registration", decode.string) 198 - use is_active <- decode.field("is_active", decode.bool) 199 - 200 - decode.success(RequestBody( 201 - full_name:, 202 - email:, 203 - user_role:, 204 - registration:, 205 - is_active:, 206 - )) 207 - } 208 - 209 - type RequestBody { 210 - RequestBody( 211 - full_name: String, 212 - email: String, 213 - user_role: role.Role, 214 - registration: String, 215 - is_active: Bool, 216 - ) 217 - }
+18 -20
src/app/domain/user/update_user_profile.gleam
··· 50 50 fn handle_error(err: UpdateProfileError) -> wisp.Response { 51 51 case err { 52 52 Authentication(err) -> user.handle_authentication_error(err) 53 - 54 - NotFound(id) -> { 55 - let body = "Usuário não encontrado" <> uuid.to_string(id) 56 - wisp.Text(body) 53 + Database(err) -> handle_database_error(err) 54 + NotFound(id) -> 55 + wisp.Text("Usuário não encontrado" <> uuid.to_string(id)) 57 56 |> wisp.set_body(wisp.not_found(), _) 58 - } 57 + } 58 + } 59 59 60 - Database(err) -> { 61 - case err { 62 - pog.ConstraintViolated(_, _, constraint: "user_account_email_key") -> { 63 - "Email já cadastrado. Por favor, utilize um diferente" 64 - |> wisp.Text 65 - |> wisp.set_body(wisp.response(409), _) 66 - } 67 - 68 - pog.ConstraintViolated(_, _, constraint: "user_account_phone_key") -> { 69 - "Telefone já cadastrado. Por favor, utilize um diferente" 70 - |> wisp.Text 71 - |> wisp.set_body(wisp.response(409), _) 72 - } 60 + fn handle_database_error(err: pog.QueryError) { 61 + case err { 62 + pog.ConstraintViolated(_, _, constraint: "user_account_email_key") -> { 63 + "Email já cadastrado. Por favor, utilize um diferente" 64 + |> wisp.Text 65 + |> wisp.set_body(wisp.response(409), _) 66 + } 73 67 74 - err -> web.handle_database_error(err) 75 - } 68 + pog.ConstraintViolated(_, _, constraint: "user_account_phone_key") -> { 69 + "Telefone já cadastrado. Por favor, utilize um diferente" 70 + |> wisp.Text 71 + |> wisp.set_body(wisp.response(409), _) 76 72 } 73 + 74 + other -> web.handle_database_error(other) 77 75 } 78 76 } 79 77