Skip to content

Commit 983cdda

Browse files
authored
models/crate_owner_invitation: Extract AcceptError enum (#10551)
This remove the tight coupling between the `AppResult`/`BoxedAppError` and the model, and moves the conversion into an HTTP response into the controller code.
1 parent c9d3f61 commit 983cdda

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

src/controllers/crate_owner_invitation.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use crate::app::AppState;
22
use crate::auth::AuthCheck;
33
use crate::auth::Authentication;
44
use crate::controllers::helpers::pagination::{Page, PaginationOptions, PaginationQueryParams};
5+
use crate::models::crate_owner_invitation::AcceptError;
56
use crate::models::{Crate, CrateOwnerInvitation, Rights, User};
67
use crate::schema::{crate_owner_invitations, crates, users};
7-
use crate::util::errors::{bad_request, forbidden, internal, AppResult, BoxedAppError};
8+
use crate::util::errors::{bad_request, custom, forbidden, internal, AppResult, BoxedAppError};
89
use crate::util::RequestUtils;
910
use crate::views::{
1011
EncodableCrateOwnerInvitation, EncodableCrateOwnerInvitationV1, EncodablePublicUser,
@@ -20,6 +21,7 @@ use diesel::prelude::*;
2021
use diesel::sql_types::Bool;
2122
use diesel_async::{AsyncPgConnection, RunQueryDsl};
2223
use http::request::Parts;
24+
use http::StatusCode;
2325
use indexmap::IndexMap;
2426
use std::collections::{HashMap, HashSet};
2527

@@ -380,3 +382,19 @@ pub async fn accept_crate_owner_invitation_with_token(
380382
},
381383
}))
382384
}
385+
386+
impl From<AcceptError> for BoxedAppError {
387+
fn from(error: AcceptError) -> Self {
388+
match error {
389+
AcceptError::Diesel(error) => error.into(),
390+
AcceptError::Expired { crate_name } => {
391+
let detail = format!(
392+
"The invitation to become an owner of the {crate_name} crate expired. \
393+
Please reach out to an owner of the crate to request a new invitation.",
394+
);
395+
396+
custom(StatusCode::GONE, detail)
397+
}
398+
}
399+
}
400+
}

src/models.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub mod helpers;
2222

2323
mod action;
2424
pub mod category;
25-
mod crate_owner_invitation;
25+
pub mod crate_owner_invitation;
2626
pub mod default_versions;
2727
mod deleted_crate;
2828
pub mod dependency;

src/models/crate_owner_invitation.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ use chrono::{NaiveDateTime, Utc};
22
use diesel::prelude::*;
33
use diesel_async::scoped_futures::ScopedFutureExt;
44
use diesel_async::{AsyncConnection, AsyncPgConnection, RunQueryDsl};
5-
use http::StatusCode;
65
use secrecy::SecretString;
76

87
use crate::config;
98
use crate::models::{CrateOwner, OwnerKind};
109
use crate::schema::{crate_owner_invitations, crate_owners, crates};
11-
use crate::util::errors::{custom, AppResult};
1210

1311
#[derive(Debug)]
1412
pub enum NewCrateOwnerInvitationOutcome {
@@ -109,7 +107,7 @@ impl CrateOwnerInvitation {
109107
self,
110108
conn: &mut AsyncPgConnection,
111109
config: &config::Server,
112-
) -> AppResult<()> {
110+
) -> Result<(), AcceptError> {
113111
use diesel_async::scoped_futures::ScopedFutureExt;
114112
use diesel_async::{AsyncConnection, RunQueryDsl};
115113

@@ -120,12 +118,7 @@ impl CrateOwnerInvitation {
120118
.first(conn)
121119
.await?;
122120

123-
let detail = format!(
124-
"The invitation to become an owner of the {crate_name} crate expired. \
125-
Please reach out to an owner of the crate to request a new invitation.",
126-
);
127-
128-
return Err(custom(StatusCode::GONE, detail));
121+
return Err(AcceptError::Expired { crate_name });
129122
}
130123

131124
conn.transaction(|conn| {
@@ -170,3 +163,11 @@ impl CrateOwnerInvitation {
170163
self.created_at + config.ownership_invitations_expiration
171164
}
172165
}
166+
167+
#[derive(Debug, thiserror::Error)]
168+
pub enum AcceptError {
169+
#[error(transparent)]
170+
Diesel(#[from] diesel::result::Error),
171+
#[error("The invitation has expired")]
172+
Expired { crate_name: String },
173+
}

0 commit comments

Comments
 (0)