Skip to content

Commit 4f43557

Browse files
committed
use custom From<anyhow::Error> for AxumNope
1 parent 8df7fbc commit 4f43557

File tree

3 files changed

+22
-67
lines changed

3 files changed

+22
-67
lines changed

src/utils/mod.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -107,27 +107,9 @@ where
107107
F: FnOnce() -> Result<R> + Send + 'static,
108108
R: Send + 'static,
109109
{
110-
let result = tokio::task::spawn_blocking(f)
110+
tokio::task::spawn_blocking(f)
111111
.await
112-
.context("failed to join thread")?;
113-
114-
if cfg!(debug_assertions) {
115-
// Since `AxumNope` can also be silently converted into
116-
// `anyhow::Error`, someone accidentally using this method
117-
// instead of `web::error::spawn_blocking_web` can lead to
118-
// a more specific AxumNope error with a specific status code
119-
// being silently converted into an anyhow::Error, so a server
120-
// error with status 500.
121-
if let Err(ref err) = result {
122-
use crate::web::error::AxumNope;
123-
assert!(
124-
err.downcast_ref::<AxumNope>().is_none(),
125-
"AxumNope found inside anyhow::Error, this is likely a problem."
126-
);
127-
}
128-
}
129-
130-
result
112+
.context("failed to join thread")?
131113
}
132114

133115
#[cfg(test)]

src/web/crate_details.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::error::spawn_blocking_web;
21
use super::{markdown, match_version, MatchSemver, MetaData};
32
use crate::utils::{get_correct_docsrs_style_file, report_error, spawn_blocking};
43
use crate::{
@@ -10,7 +9,7 @@ use crate::{
109
error::{AxumNope, AxumResult},
1110
},
1211
};
13-
use anyhow::{anyhow, Context as _};
12+
use anyhow::anyhow;
1413
use axum::{
1514
extract::{Extension, Path},
1615
response::{IntoResponse, Response as AxumResponse},
@@ -326,14 +325,15 @@ pub(crate) async fn crate_details_handler(
326325
.into_response());
327326
}
328327

329-
let found_version = spawn_blocking_web({
328+
let found_version = spawn_blocking({
330329
let pool = pool.clone();
331330
let params = params.clone();
332331
move || {
333-
let mut conn = pool.get().context("could not get connection from pool")?;
334-
match_version(&mut conn, &params.name, params.version.as_deref())
335-
.and_then(|m| m.assume_exact())
336-
.map_err(Into::<AxumNope>::into)
332+
let mut conn = pool.get()?;
333+
Ok(
334+
match_version(&mut conn, &params.name, params.version.as_deref())
335+
.and_then(|m| m.assume_exact())?,
336+
)
337337
}
338338
})
339339
.await?;

src/web/error.rs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::{
44
db::PoolError,
55
web::{page::WebPage, releases::Search, AxumErrorPage, ErrorPage},
66
};
7-
use anyhow::Context as _;
87
use axum::{
98
http::StatusCode,
109
response::{IntoResponse, Response as AxumResponse},
@@ -157,7 +156,7 @@ pub enum AxumNope {
157156
#[error("Internal server error")]
158157
InternalServerError,
159158
#[error("internal error")]
160-
InternalError(#[from] anyhow::Error),
159+
InternalError(anyhow::Error),
161160
}
162161

163162
impl IntoResponse for AxumNope {
@@ -235,6 +234,18 @@ impl IntoResponse for AxumNope {
235234
}
236235
}
237236

237+
impl From<anyhow::Error> for AxumNope {
238+
fn from(err: anyhow::Error) -> Self {
239+
match err.downcast::<AxumNope>() {
240+
Ok(axum_nope) => axum_nope,
241+
Err(err) => match err.downcast::<Nope>() {
242+
Ok(iron_nope) => AxumNope::from(iron_nope),
243+
Err(err) => AxumNope::InternalError(err),
244+
},
245+
}
246+
}
247+
}
248+
238249
impl From<Nope> for AxumNope {
239250
fn from(err: Nope) -> Self {
240251
match err {
@@ -251,44 +262,6 @@ impl From<Nope> for AxumNope {
251262

252263
pub(crate) type AxumResult<T> = Result<T, AxumNope>;
253264

254-
/// spawn-blocking helper for usage in axum requests.
255-
///
256-
/// Should be used when spawning tasks from inside web-handlers
257-
/// that return AxumNope as error. The join-error will also be
258-
/// converted into an `anyhow::Error`. Any standard AxumNope
259-
/// will be left intact so the error-handling can generate the
260-
/// correct status-page with the correct status code.
261-
///
262-
/// Examples:
263-
///
264-
/// with standard `tokio::task::spawn_blocking`:
265-
/// ```ignore
266-
/// let data = spawn_blocking(move || -> Result<_, AxumNope> {
267-
/// let data = get_the_data()?;
268-
/// Ok(data)
269-
/// })
270-
/// .await
271-
/// .context("failed to join thread")??;
272-
/// ```
273-
///
274-
/// with this helper function:
275-
/// ```ignore
276-
/// let data = spawn_blocking(move || {
277-
/// let data = get_the_data()?;
278-
/// Ok(data)
279-
/// })
280-
/// .await?
281-
/// ```
282-
pub(crate) async fn spawn_blocking_web<F, R>(f: F) -> AxumResult<R>
283-
where
284-
F: FnOnce() -> AxumResult<R> + Send + 'static,
285-
R: Send + 'static,
286-
{
287-
tokio::task::spawn_blocking(f)
288-
.await
289-
.context("failed to join thread")?
290-
}
291-
292265
#[cfg(test)]
293266
mod tests {
294267
use crate::test::wrapper;

0 commit comments

Comments
 (0)