Skip to content

Commit b53bc3a

Browse files
committed
errors: Inline chain_error() method
Using `map_err()` instead is just a few characters more, but makes it more clear how the original error is chained onto the new error
1 parent 8a4dcc0 commit b53bc3a

File tree

8 files changed

+24
-44
lines changed

8 files changed

+24
-44
lines changed

src/controllers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod prelude {
1919

2020
pub use crate::db::RequestTransaction;
2121
pub use crate::middleware::app::RequestApp;
22-
pub use crate::util::errors::{cargo_err, AppError, AppResult, ChainError}; // TODO: Remove cargo_err from here
22+
pub use crate::util::errors::{cargo_err, AppError, AppResult}; // TODO: Remove cargo_err from here
2323
pub use crate::util::{AppResponse, EndpointResult};
2424

2525
use indexmap::IndexMap;

src/controllers/user/me.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ pub fn regenerate_token_and_send(req: &mut dyn RequestExt) -> EndpointResult {
187187

188188
let param_user_id = req.params()["user_id"]
189189
.parse::<i32>()
190-
.chain_error(|| bad_request("invalid user_id"))?;
190+
.map_err(|err| err.chain(bad_request("invalid user_id")))?;
191191
let authenticated_user = req.authenticate()?;
192192
let conn = req.db_conn()?;
193193
let user = authenticated_user.user();

src/controllers/user/other.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::controllers::frontend_prelude::*;
22

33
use crate::models::{CrateOwner, OwnerKind, User};
44
use crate::schema::{crate_owners, crates, users};
5-
use crate::util::errors::ChainError;
65
use crate::views::EncodablePublicUser;
76

87
/// Handles the `GET /users/:user_id` route.
@@ -25,7 +24,7 @@ pub fn stats(req: &mut dyn RequestExt) -> EndpointResult {
2524

2625
let user_id = &req.params()["user_id"]
2726
.parse::<i32>()
28-
.chain_error(|| bad_request("invalid user_id"))?;
27+
.map_err(|err| err.chain(bad_request("invalid user_id")))?;
2928
let conn = req.db_conn()?;
3029

3130
let data: i64 = CrateOwner::by_owner_kind(OwnerKind::User)

src/controllers/user/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub fn authorize(req: &mut dyn RequestExt) -> EndpointResult {
9090
.github_oauth
9191
.exchange_code(code)
9292
.request(http_client)
93-
.chain_error(|| server_error("Error obtaining token"))?;
93+
.map_err(|err| err.chain(server_error("Error obtaining token")))?;
9494
let token = token.access_token();
9595

9696
// Fetch the user info from GitHub using the access token we just got and create a user record

src/controllers/util.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use super::prelude::*;
66
use crate::middleware::log_request;
77
use crate::models::{ApiToken, User};
88
use crate::util::errors::{
9-
account_locked, forbidden, internal, AppError, AppResult, ChainError,
10-
InsecurelyGeneratedTokenRevoked,
9+
account_locked, forbidden, internal, AppError, AppResult, InsecurelyGeneratedTokenRevoked,
1110
};
1211

1312
#[derive(Debug)]
@@ -62,8 +61,7 @@ fn verify_origin(req: &dyn RequestExt) -> AppResult<()> {
6261
"only same-origin requests can be authenticated. got {:?}",
6362
bad_origin
6463
);
65-
return Err(internal(&error_message))
66-
.chain_error(|| Box::new(forbidden()) as Box<dyn AppError>);
64+
return Err(internal(&error_message).chain(forbidden()));
6765
}
6866
Ok(())
6967
}
@@ -76,7 +74,7 @@ fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
7674

7775
if let Some(id) = user_id_from_session {
7876
let user = User::find(&conn, id)
79-
.chain_error(|| internal("user_id from cookie not found in database"))?;
77+
.map_err(|err| err.chain(internal("user_id from cookie not found in database")))?;
8078

8179
return Ok(AuthenticatedUser {
8280
user,
@@ -100,7 +98,7 @@ fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
10098
})?;
10199

102100
let user = User::find(&conn, token.user_id)
103-
.chain_error(|| internal("user_id from token not found in database"))?;
101+
.map_err(|err| err.chain(internal("user_id from token not found in database")))?;
104102

105103
return Ok(AuthenticatedUser {
106104
user,
@@ -109,7 +107,7 @@ fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
109107
}
110108

111109
// Unable to authenticate the user
112-
return Err(internal("no cookie session or auth header found")).chain_error(forbidden);
110+
return Err(internal("no cookie session or auth header found").chain(forbidden()));
113111
}
114112

115113
impl<'a> UserAuthenticationExt for dyn RequestExt + 'a {

src/router.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,7 @@ impl<H: Handler> Handler for R<H> {
179179
#[cfg(test)]
180180
mod tests {
181181
use super::*;
182-
use crate::util::errors::{
183-
bad_request, cargo_err, forbidden, internal, not_found, AppError, ChainError,
184-
};
182+
use crate::util::errors::{bad_request, cargo_err, forbidden, internal, not_found, AppError};
185183
use crate::util::EndpointResult;
186184

187185
use conduit::StatusCode;
@@ -227,8 +225,8 @@ mod tests {
227225
let response = C(|_| {
228226
Err("-1"
229227
.parse::<u8>()
230-
.chain_error(|| internal("middle error"))
231-
.chain_error(|| bad_request("outer user facing error"))
228+
.map_err(|err| err.chain(internal("middle error")))
229+
.map_err(|err| err.chain(bad_request("outer user facing error")))
232230
.unwrap_err())
233231
})
234232
.call(&mut req)

src/uploaders.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use flate2::read::GzDecoder;
44
use reqwest::{blocking::Client, header};
55
use sha2::{Digest, Sha256};
66

7-
use crate::util::errors::{cargo_err, internal, AppResult, ChainError};
7+
use crate::util::errors::{cargo_err, internal, AppError, AppResult};
88
use crate::util::{LimitErrorReader, Maximums};
99

1010
use std::env;
@@ -200,8 +200,10 @@ fn verify_tarball(
200200
let mut archive = tar::Archive::new(decoder);
201201
let prefix = format!("{}-{}", krate.name, vers);
202202
for entry in archive.entries()? {
203-
let entry = entry.chain_error(|| {
204-
cargo_err("uploaded tarball is malformed or too large when decompressed")
203+
let entry = entry.map_err(|err| {
204+
err.chain(cargo_err(
205+
"uploaded tarball is malformed or too large when decompressed",
206+
))
205207
})?;
206208

207209
// Verify that all entries actually start with `$name-$vers/`.

src/util/errors.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -142,29 +142,12 @@ pub type AppResult<T> = Result<T, Box<dyn AppError>>;
142142
// =============================================================================
143143
// Chaining errors
144144

145-
pub trait ChainError<T> {
146-
fn chain_error<E, F>(self, callback: F) -> AppResult<T>
147-
where
148-
E: AppError,
149-
F: FnOnce() -> E;
150-
}
151-
152145
#[derive(Debug)]
153146
struct ChainedError<E> {
154147
error: E,
155148
cause: Box<dyn AppError>,
156149
}
157150

158-
impl<T, E: AppError> ChainError<T> for Result<T, E> {
159-
fn chain_error<E2, C>(self, callback: C) -> AppResult<T>
160-
where
161-
E2: AppError,
162-
C: FnOnce() -> E2,
163-
{
164-
self.map_err(move |err| err.chain(callback()))
165-
}
166-
}
167-
168151
impl<E: AppError> AppError for ChainedError<E> {
169152
fn response(&self) -> Option<AppResponse> {
170153
self.error.response()
@@ -252,15 +235,15 @@ pub(crate) fn std_error(e: Box<dyn AppError>) -> Box<dyn Error + Send> {
252235
fn chain_error_internal() {
253236
assert_eq!(
254237
Err::<(), _>(internal("inner"))
255-
.chain_error(|| internal("middle"))
256-
.chain_error(|| internal("outer"))
238+
.map_err(|err| err.chain(internal("middle")))
239+
.map_err(|err| err.chain(internal("outer")))
257240
.unwrap_err()
258241
.to_string(),
259242
"outer caused by middle caused by inner"
260243
);
261244
assert_eq!(
262245
Err::<(), _>(internal("inner"))
263-
.chain_error(|| internal("outer"))
246+
.map_err(|err| err.chain(internal("outer")))
264247
.unwrap_err()
265248
.to_string(),
266249
"outer caused by inner"
@@ -269,14 +252,14 @@ fn chain_error_internal() {
269252
// Don't do this, the user will see a generic 500 error instead of the intended message
270253
assert_eq!(
271254
Err::<(), _>(cargo_err("inner"))
272-
.chain_error(|| internal("outer"))
255+
.map_err(|err| err.chain(internal("outer")))
273256
.unwrap_err()
274257
.to_string(),
275258
"outer caused by inner"
276259
);
277260
assert_eq!(
278261
Err::<(), _>(forbidden())
279-
.chain_error(|| internal("outer"))
262+
.map_err(|err| err.chain(internal("outer")))
280263
.unwrap_err()
281264
.to_string(),
282265
"outer caused by must be logged in to perform that action"
@@ -288,7 +271,7 @@ fn chain_error_user_facing() {
288271
// Do this rarely, the user will only see the outer error
289272
assert_eq!(
290273
Err::<(), _>(cargo_err("inner"))
291-
.chain_error(|| cargo_err("outer"))
274+
.map_err(|err| err.chain(cargo_err("outer")))
292275
.unwrap_err()
293276
.to_string(),
294277
"outer caused by inner" // never logged
@@ -298,7 +281,7 @@ fn chain_error_user_facing() {
298281
// The inner error never bubbles up to the logging middleware
299282
assert_eq!(
300283
Err::<(), _>(std::io::Error::from(std::io::ErrorKind::PermissionDenied))
301-
.chain_error(|| cargo_err("outer"))
284+
.map_err(|err| err.chain(cargo_err("outer")))
302285
.unwrap_err()
303286
.to_string(),
304287
"outer caused by permission denied" // never logged

0 commit comments

Comments
 (0)