Skip to content

Commit 3854751

Browse files
committed
models/version: Move bad_request() error transformation into controller code
The model layer is not supposed to know anything about HTTP API errors...
1 parent a3d6059 commit 3854751

File tree

2 files changed

+16
-23
lines changed

2 files changed

+16
-23
lines changed

src/controllers/krate/publish.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ pub async fn publish(app: AppState, req: BytesRequest) -> AppResult<Json<GoodCra
359359
let hex_cksum: String = Sha256::digest(&tarball_bytes).encode_hex();
360360

361361
// Persist the new version of this crate
362-
let version = NewVersion::builder(krate.id, &version_string)
362+
let new_version = NewVersion::builder(krate.id, &version_string)
363363
.features(serde_json::to_value(&features)?)
364364
.maybe_license(license.as_deref())
365365
// Downcast is okay because the file length must be less than the max upload size
@@ -371,8 +371,18 @@ pub async fn publish(app: AppState, req: BytesRequest) -> AppResult<Json<GoodCra
371371
.maybe_rust_version(rust_version.as_deref())
372372
.has_lib(tarball_info.manifest.lib.is_some())
373373
.bin_names(bin_names.as_slice())
374-
.build()
375-
.save(conn, &verified_email_address)?;
374+
.build();
375+
376+
let version = match new_version.save(conn, &verified_email_address) {
377+
Err(diesel::result::Error::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _)) => {
378+
return Err(bad_request(format_args!(
379+
"crate version `{}` is already uploaded",
380+
new_version.num_no_build
381+
)));
382+
},
383+
Err(error) => return Err(error.into()),
384+
Ok(version) => version,
385+
};
376386

377387
insert_version_owner_action(
378388
conn,

src/models/version.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use crates_io_index::features::FeaturesMap;
66
use diesel::prelude::*;
77
use serde::Deserialize;
88

9-
use crate::util::errors::{bad_request, AppResult};
10-
119
use crate::models::{Crate, Dependency, User};
1210
use crate::schema::*;
1311
use crate::util::diesel::Conn;
@@ -85,7 +83,7 @@ pub struct NewVersion<'a> {
8583
#[builder(start_fn)]
8684
num: &'a str,
8785
#[builder(default = strip_build_metadata(num))]
88-
num_no_build: &'a str,
86+
pub num_no_build: &'a str,
8987
created_at: Option<&'a NaiveDateTime>,
9088
yanked: Option<bool>,
9189
#[builder(default = serde_json::Value::Object(Default::default()))]
@@ -102,21 +100,11 @@ pub struct NewVersion<'a> {
102100
}
103101

104102
impl NewVersion<'_> {
105-
pub fn save(&self, conn: &mut impl Conn, published_by_email: &str) -> AppResult<Version> {
103+
pub fn save(&self, conn: &mut impl Conn, published_by_email: &str) -> QueryResult<Version> {
106104
use diesel::insert_into;
107105

108106
conn.transaction(|conn| {
109-
let version: Version = match insert_into(versions::table).values(self).get_result(conn)
110-
{
111-
Err(error) if is_unique_violation(&error) => {
112-
return Err(bad_request(format_args!(
113-
"crate version `{}` is already uploaded",
114-
self.num_no_build
115-
)));
116-
}
117-
Err(error) => return Err(error.into()),
118-
Ok(version) => version,
119-
};
107+
let version: Version = insert_into(versions::table).values(self).get_result(conn)?;
120108

121109
insert_into(versions_published_by::table)
122110
.values((
@@ -136,11 +124,6 @@ fn strip_build_metadata(version: &str) -> &str {
136124
.unwrap_or(version)
137125
}
138126

139-
fn is_unique_violation(error: &diesel::result::Error) -> bool {
140-
use diesel::result::{DatabaseErrorKind::UniqueViolation, Error};
141-
matches!(error, Error::DatabaseError(UniqueViolation, _))
142-
}
143-
144127
/// The highest version (semver order) and the most recently updated version.
145128
/// Typically used for a single crate.
146129
#[derive(Debug, Clone, Eq, PartialEq)]

0 commit comments

Comments
 (0)