Skip to content

Commit b73d864

Browse files
committed
fix(api): Axum API, error should return a 500 status code
If the handlers return an error Axum does not automatically return an error HTTP code. See https://docs.rs/axum/latest/axum/error_handling/index.html. You have to convert the error into an error response.
1 parent b4744e7 commit b73d864

File tree

5 files changed

+102
-86
lines changed

5 files changed

+102
-86
lines changed

src/web/api/v1/contexts/category/handlers.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
use std::sync::Arc;
44

55
use axum::extract::{self, State};
6-
use axum::response::Json;
6+
use axum::response::{IntoResponse, Json, Response};
77

88
use super::forms::{AddCategoryForm, DeleteCategoryForm};
99
use super::responses::{added_category, deleted_category};
1010
use crate::common::AppData;
11-
use crate::databases::database::{self, Category};
12-
use crate::errors::ServiceError;
1311
use crate::web::api::v1::extractors::bearer_token::Extract;
14-
use crate::web::api::v1::responses::{self, OkResponseData};
12+
use crate::web::api::v1::responses::{self};
1513

1614
/// It handles the request to get all the categories.
1715
///
@@ -27,12 +25,10 @@ use crate::web::api::v1::responses::{self, OkResponseData};
2725
///
2826
/// It returns an error if there is a database error.
2927
#[allow(clippy::unused_async)]
30-
pub async fn get_all_handler(
31-
State(app_data): State<Arc<AppData>>,
32-
) -> Result<Json<responses::OkResponseData<Vec<Category>>>, database::Error> {
28+
pub async fn get_all_handler(State(app_data): State<Arc<AppData>>) -> Response {
3329
match app_data.category_repository.get_all().await {
34-
Ok(categories) => Ok(Json(responses::OkResponseData { data: categories })),
35-
Err(error) => Err(error),
30+
Ok(categories) => Json(responses::OkResponseData { data: categories }).into_response(),
31+
Err(error) => error.into_response(),
3632
}
3733
}
3834

@@ -49,12 +45,15 @@ pub async fn add_handler(
4945
State(app_data): State<Arc<AppData>>,
5046
Extract(maybe_bearer_token): Extract,
5147
extract::Json(category_form): extract::Json<AddCategoryForm>,
52-
) -> Result<Json<OkResponseData<String>>, ServiceError> {
53-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
48+
) -> Response {
49+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
50+
Ok(user_id) => user_id,
51+
Err(error) => return error.into_response(),
52+
};
5453

5554
match app_data.category_service.add_category(&category_form.name, &user_id).await {
56-
Ok(_) => Ok(added_category(&category_form.name)),
57-
Err(error) => Err(error),
55+
Ok(_) => added_category(&category_form.name).into_response(),
56+
Err(error) => error.into_response(),
5857
}
5958
}
6059

@@ -71,15 +70,18 @@ pub async fn delete_handler(
7170
State(app_data): State<Arc<AppData>>,
7271
Extract(maybe_bearer_token): Extract,
7372
extract::Json(category_form): extract::Json<DeleteCategoryForm>,
74-
) -> Result<Json<OkResponseData<String>>, ServiceError> {
73+
) -> Response {
7574
// code-review: why do we need to send the whole category object to delete it?
7675
// And we should use the ID instead of the name, because the name could change
7776
// or we could add support for multiple languages.
7877

79-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
78+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
79+
Ok(user_id) => user_id,
80+
Err(error) => return error.into_response(),
81+
};
8082

8183
match app_data.category_service.delete_category(&category_form.name, &user_id).await {
82-
Ok(_) => Ok(deleted_category(&category_form.name)),
83-
Err(error) => Err(error),
84+
Ok(_) => deleted_category(&category_form.name).into_response(),
85+
Err(error) => error.into_response(),
8486
}
8587
}

src/web/api/v1/contexts/settings/handlers.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
use std::sync::Arc;
44

55
use axum::extract::{self, State};
6-
use axum::response::Json;
6+
use axum::response::{IntoResponse, Json, Response};
77

88
use crate::common::AppData;
9-
use crate::config::{ConfigurationPublic, TorrustBackend};
10-
use crate::errors::ServiceError;
9+
use crate::config::TorrustBackend;
1110
use crate::web::api::v1::extractors::bearer_token::Extract;
12-
use crate::web::api::v1::responses::{self, OkResponseData};
11+
use crate::web::api::v1::responses::{self};
1312

1413
/// Get all settings.
1514
///
@@ -18,31 +17,34 @@ use crate::web::api::v1::responses::{self, OkResponseData};
1817
/// This function will return an error if the user does not have permission to
1918
/// view all the settings.
2019
#[allow(clippy::unused_async)]
21-
pub async fn get_all_handler(
22-
State(app_data): State<Arc<AppData>>,
23-
Extract(maybe_bearer_token): Extract,
24-
) -> Result<Json<OkResponseData<TorrustBackend>>, ServiceError> {
25-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
20+
pub async fn get_all_handler(State(app_data): State<Arc<AppData>>, Extract(maybe_bearer_token): Extract) -> Response {
21+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
22+
Ok(user_id) => user_id,
23+
Err(error) => return error.into_response(),
24+
};
2625

27-
let all_settings = app_data.settings_service.get_all(&user_id).await?;
26+
let all_settings = match app_data.settings_service.get_all(&user_id).await {
27+
Ok(all_settings) => all_settings,
28+
Err(error) => return error.into_response(),
29+
};
2830

29-
Ok(Json(responses::OkResponseData { data: all_settings }))
31+
Json(responses::OkResponseData { data: all_settings }).into_response()
3032
}
3133

3234
/// Get public Settings.
3335
#[allow(clippy::unused_async)]
34-
pub async fn get_public_handler(State(app_data): State<Arc<AppData>>) -> Json<responses::OkResponseData<ConfigurationPublic>> {
36+
pub async fn get_public_handler(State(app_data): State<Arc<AppData>>) -> Response {
3537
let public_settings = app_data.settings_service.get_public().await;
3638

37-
Json(responses::OkResponseData { data: public_settings })
39+
Json(responses::OkResponseData { data: public_settings }).into_response()
3840
}
3941

4042
/// Get website name.
4143
#[allow(clippy::unused_async)]
42-
pub async fn get_site_name_handler(State(app_data): State<Arc<AppData>>) -> Json<responses::OkResponseData<String>> {
44+
pub async fn get_site_name_handler(State(app_data): State<Arc<AppData>>) -> Response {
4345
let site_name = app_data.settings_service.get_site_name().await;
4446

45-
Json(responses::OkResponseData { data: site_name })
47+
Json(responses::OkResponseData { data: site_name }).into_response()
4648
}
4749

4850
/// Update all the settings.
@@ -59,10 +61,16 @@ pub async fn update_handler(
5961
State(app_data): State<Arc<AppData>>,
6062
Extract(maybe_bearer_token): Extract,
6163
extract::Json(torrust_backend): extract::Json<TorrustBackend>,
62-
) -> Result<Json<OkResponseData<TorrustBackend>>, ServiceError> {
63-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
64+
) -> Response {
65+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
66+
Ok(user_id) => user_id,
67+
Err(error) => return error.into_response(),
68+
};
6469

65-
let new_settings = app_data.settings_service.update_all(torrust_backend, &user_id).await?;
70+
let new_settings = match app_data.settings_service.update_all(torrust_backend, &user_id).await {
71+
Ok(new_settings) => new_settings,
72+
Err(error) => return error.into_response(),
73+
};
6674

67-
Ok(Json(responses::OkResponseData { data: new_settings }))
75+
Json(responses::OkResponseData { data: new_settings }).into_response()
6876
}

src/web/api/v1/contexts/tag/handlers.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
use std::sync::Arc;
44

55
use axum::extract::{self, State};
6-
use axum::response::Json;
6+
use axum::response::{IntoResponse, Json, Response};
77

88
use super::forms::{AddTagForm, DeleteTagForm};
99
use super::responses::{added_tag, deleted_tag};
1010
use crate::common::AppData;
11-
use crate::databases::database;
12-
use crate::errors::ServiceError;
13-
use crate::models::torrent_tag::{TagId, TorrentTag};
1411
use crate::web::api::v1::extractors::bearer_token::Extract;
15-
use crate::web::api::v1::responses::{self, OkResponseData};
12+
use crate::web::api::v1::responses::{self};
1613

1714
/// It handles the request to get all the tags.
1815
///
@@ -28,12 +25,10 @@ use crate::web::api::v1::responses::{self, OkResponseData};
2825
///
2926
/// It returns an error if there is a database error.
3027
#[allow(clippy::unused_async)]
31-
pub async fn get_all_handler(
32-
State(app_data): State<Arc<AppData>>,
33-
) -> Result<Json<responses::OkResponseData<Vec<TorrentTag>>>, database::Error> {
28+
pub async fn get_all_handler(State(app_data): State<Arc<AppData>>) -> Response {
3429
match app_data.tag_repository.get_all().await {
35-
Ok(tags) => Ok(Json(responses::OkResponseData { data: tags })),
36-
Err(error) => Err(error),
30+
Ok(tags) => Json(responses::OkResponseData { data: tags }).into_response(),
31+
Err(error) => error.into_response(),
3732
}
3833
}
3934

@@ -50,12 +45,15 @@ pub async fn add_handler(
5045
State(app_data): State<Arc<AppData>>,
5146
Extract(maybe_bearer_token): Extract,
5247
extract::Json(add_tag_form): extract::Json<AddTagForm>,
53-
) -> Result<Json<OkResponseData<String>>, ServiceError> {
54-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
48+
) -> Response {
49+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
50+
Ok(user_id) => user_id,
51+
Err(error) => return error.into_response(),
52+
};
5553

5654
match app_data.tag_service.add_tag(&add_tag_form.name, &user_id).await {
57-
Ok(_) => Ok(added_tag(&add_tag_form.name)),
58-
Err(error) => Err(error),
55+
Ok(_) => added_tag(&add_tag_form.name).into_response(),
56+
Err(error) => error.into_response(),
5957
}
6058
}
6159

@@ -72,11 +70,14 @@ pub async fn delete_handler(
7270
State(app_data): State<Arc<AppData>>,
7371
Extract(maybe_bearer_token): Extract,
7472
extract::Json(delete_tag_form): extract::Json<DeleteTagForm>,
75-
) -> Result<Json<OkResponseData<TagId>>, ServiceError> {
76-
let user_id = app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await?;
73+
) -> Response {
74+
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
75+
Ok(user_id) => user_id,
76+
Err(error) => return error.into_response(),
77+
};
7778

7879
match app_data.tag_service.delete_tag(&delete_tag_form.tag_id, &user_id).await {
79-
Ok(_) => Ok(deleted_tag(delete_tag_form.tag_id)),
80-
Err(error) => Err(error),
80+
Ok(_) => deleted_tag(delete_tag_form.tag_id).into_response(),
81+
Err(error) => error.into_response(),
8182
}
8283
}

src/web/api/v1/contexts/torrent/handlers.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ pub async fn upload_torrent_handler(
3939
) -> Response {
4040
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
4141
Ok(user_id) => user_id,
42-
Err(err) => return err.into_response(),
42+
Err(error) => return error.into_response(),
4343
};
4444

4545
let torrent_request = match get_torrent_request_from_payload(multipart).await {
4646
Ok(torrent_request) => torrent_request,
47-
Err(err) => return err.into_response(),
47+
Err(error) => return error.into_response(),
4848
};
4949

5050
let info_hash = torrent_request.torrent.info_hash().clone();
@@ -73,12 +73,12 @@ pub async fn download_torrent_handler(
7373

7474
let opt_user_id = match get_optional_logged_in_user(maybe_bearer_token, app_data.clone()).await {
7575
Ok(opt_user_id) => opt_user_id,
76-
Err(err) => return err.into_response(),
76+
Err(error) => return error.into_response(),
7777
};
7878

7979
let torrent = match app_data.torrent_service.get_torrent(&info_hash, opt_user_id).await {
8080
Ok(torrent) => torrent,
81-
Err(err) => return err.into_response(),
81+
Err(error) => return error.into_response(),
8282
};
8383

8484
let Ok(bytes) = parse_torrent::encode_torrent(&torrent) else { return ServiceError::InternalServerError.into_response() };
@@ -97,7 +97,7 @@ pub async fn download_torrent_handler(
9797
pub async fn get_torrents_handler(State(app_data): State<Arc<AppData>>, Query(criteria): Query<ListingRequest>) -> Response {
9898
match app_data.torrent_service.generate_torrent_info_listing(&criteria).await {
9999
Ok(torrents_response) => Json(OkResponseData { data: torrents_response }).into_response(),
100-
Err(err) => err.into_response(),
100+
Err(error) => error.into_response(),
101101
}
102102
}
103103

@@ -119,12 +119,12 @@ pub async fn get_torrent_info_handler(
119119

120120
let opt_user_id = match get_optional_logged_in_user(maybe_bearer_token, app_data.clone()).await {
121121
Ok(opt_user_id) => opt_user_id,
122-
Err(err) => return err.into_response(),
122+
Err(error) => return error.into_response(),
123123
};
124124

125125
match app_data.torrent_service.get_torrent_info(&info_hash, opt_user_id).await {
126126
Ok(torrent_response) => Json(OkResponseData { data: torrent_response }).into_response(),
127-
Err(err) => err.into_response(),
127+
Err(error) => error.into_response(),
128128
}
129129
}
130130

@@ -148,7 +148,7 @@ pub async fn update_torrent_info_handler(
148148

149149
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
150150
Ok(user_id) => user_id,
151-
Err(err) => return err.into_response(),
151+
Err(error) => return error.into_response(),
152152
};
153153

154154
match app_data
@@ -163,7 +163,7 @@ pub async fn update_torrent_info_handler(
163163
.await
164164
{
165165
Ok(torrent_response) => Json(OkResponseData { data: torrent_response }).into_response(),
166-
Err(err) => err.into_response(),
166+
Err(error) => error.into_response(),
167167
}
168168
}
169169

@@ -186,15 +186,15 @@ pub async fn delete_torrent_handler(
186186

187187
let user_id = match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await {
188188
Ok(user_id) => user_id,
189-
Err(err) => return err.into_response(),
189+
Err(error) => return error.into_response(),
190190
};
191191

192192
match app_data.torrent_service.delete_torrent(&info_hash, &user_id).await {
193193
Ok(deleted_torrent_response) => Json(OkResponseData {
194194
data: deleted_torrent_response,
195195
})
196196
.into_response(),
197-
Err(err) => err.into_response(),
197+
Err(error) => error.into_response(),
198198
}
199199
}
200200

@@ -210,7 +210,7 @@ async fn get_optional_logged_in_user(
210210
match maybe_bearer_token {
211211
Some(bearer_token) => match app_data.auth.get_user_id_from_bearer_token(&Some(bearer_token)).await {
212212
Ok(user_id) => Ok(Some(user_id)),
213-
Err(err) => Err(err),
213+
Err(error) => Err(error),
214214
},
215215
None => Ok(None),
216216
}

0 commit comments

Comments
 (0)