From 3768b643bb7f1b51e8998acc0be04e14834a873d Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 13 Oct 2021 18:49:38 +0200 Subject: [PATCH] Dont swallow API errors (fixes #1834) --- crates/api/src/comment.rs | 22 ++--- crates/api/src/comment_report.rs | 12 +-- crates/api/src/community.rs | 66 +++++++------- crates/api/src/local_user.rs | 91 ++++++++----------- crates/api/src/post.rs | 18 ++-- crates/api/src/post_report.rs | 12 +-- crates/api/src/private_message.rs | 4 +- crates/api/src/site.rs | 14 +-- crates/api_common/src/lib.rs | 32 +++---- crates/api_crud/src/comment/create.rs | 22 ++--- crates/api_crud/src/comment/delete.rs | 6 +- crates/api_crud/src/comment/read.rs | 2 +- crates/api_crud/src/comment/update.rs | 4 +- crates/api_crud/src/community/create.rs | 12 +-- crates/api_crud/src/community/delete.rs | 6 +- crates/api_crud/src/community/read.rs | 6 +- crates/api_crud/src/community/update.rs | 4 +- crates/api_crud/src/post/create.rs | 8 +- crates/api_crud/src/post/delete.rs | 2 +- crates/api_crud/src/post/read.rs | 6 +- crates/api_crud/src/post/update.rs | 6 +- crates/api_crud/src/private_message/create.rs | 6 +- crates/api_crud/src/private_message/delete.rs | 4 +- crates/api_crud/src/private_message/update.rs | 4 +- crates/api_crud/src/site/create.rs | 4 +- crates/api_crud/src/site/read.rs | 8 +- crates/api_crud/src/site/update.rs | 6 +- crates/api_crud/src/user/create.rs | 24 ++--- crates/api_crud/src/user/delete.rs | 14 +-- crates/api_crud/src/user/read.rs | 2 +- crates/db_queries/src/lib.rs | 2 +- crates/utils/src/lib.rs | 16 +++- crates/utils/src/utils.rs | 7 +- crates/websocket/src/chat_server.rs | 6 +- 34 files changed, 224 insertions(+), 234 deletions(-) diff --git a/crates/api/src/comment.rs b/crates/api/src/comment.rs index 951bd395f..9311d7dc2 100644 --- a/crates/api/src/comment.rs +++ b/crates/api/src/comment.rs @@ -50,7 +50,7 @@ impl Perform for MarkCommentAsRead { // Verify that only the recipient can mark as read if local_user_view.person.id != orig_comment.get_recipient_id() { - return Err(ApiError::err("no_comment_edit_allowed").into()); + return Err(ApiError::err_plain("no_comment_edit_allowed").into()); } // Do the mark as read @@ -59,7 +59,7 @@ impl Perform for MarkCommentAsRead { Comment::update_read(conn, comment_id, read) }) .await? - .map_err(|_| ApiError::err("couldnt_update_comment"))?; + .map_err(|_| ApiError::err_plain("couldnt_update_comment"))?; // Refetch it let comment_id = data.comment_id; @@ -99,14 +99,14 @@ impl Perform for SaveComment { if data.save { let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form); - if blocking(context.pool(), save_comment).await?.is_err() { - return Err(ApiError::err("couldnt_save_comment").into()); - } + blocking(context.pool(), save_comment) + .await? + .map_err(|e| ApiError::err("couldnt_save_comment", e))?; } else { let unsave_comment = move |conn: &'_ _| CommentSaved::unsave(conn, &comment_saved_form); - if blocking(context.pool(), unsave_comment).await?.is_err() { - return Err(ApiError::err("couldnt_save_comment").into()); - } + blocking(context.pool(), unsave_comment) + .await? + .map_err(|e| ApiError::err("couldnt_save_comment", e))?; } let comment_id = data.comment_id; @@ -193,9 +193,9 @@ impl Perform for CreateCommentLike { if do_add { let like_form2 = like_form.clone(); let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2); - if blocking(context.pool(), like).await?.is_err() { - return Err(ApiError::err("couldnt_like_comment").into()); - } + blocking(context.pool(), like) + .await? + .map_err(|e| ApiError::err("couldnt_like_comment", e))?; Vote::send( &object, diff --git a/crates/api/src/comment_report.rs b/crates/api/src/comment_report.rs index 67bc42acc..d12b8d6f2 100644 --- a/crates/api/src/comment_report.rs +++ b/crates/api/src/comment_report.rs @@ -33,10 +33,10 @@ impl Perform for CreateCommentReport { // check size of report and check for whitespace let reason = data.reason.trim(); if reason.is_empty() { - return Err(ApiError::err("report_reason_required").into()); + return Err(ApiError::err_plain("report_reason_required").into()); } if reason.chars().count() > 1000 { - return Err(ApiError::err("report_too_long").into()); + return Err(ApiError::err_plain("report_too_long").into()); } let person_id = local_user_view.person.id; @@ -59,7 +59,7 @@ impl Perform for CreateCommentReport { CommentReport::report(conn, &report_form) }) .await? - .map_err(|_| ApiError::err("couldnt_create_report"))?; + .map_err(|e| ApiError::err("couldnt_create_report", e))?; let comment_report_view = blocking(context.pool(), move |conn| { CommentReportView::read(conn, report.id, person_id) @@ -114,9 +114,9 @@ impl Perform for ResolveCommentReport { } }; - if blocking(context.pool(), resolve_fun).await?.is_err() { - return Err(ApiError::err("couldnt_resolve_report").into()); - }; + blocking(context.pool(), resolve_fun) + .await? + .map_err(|e| ApiError::err("couldnt_resolve_report", e))?; let report_id = data.report_id; let comment_report_view = blocking(context.pool(), move |conn| { diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index f4548be6d..7a5e622ca 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -72,15 +72,15 @@ impl Perform for FollowCommunity { check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); - if blocking(context.pool(), follow).await?.is_err() { - return Err(ApiError::err("community_follower_already_exists").into()); - } + blocking(context.pool(), follow) + .await? + .map_err(|e| ApiError::err("community_follower_already_exists", e))?; } else { let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form); - if blocking(context.pool(), unfollow).await?.is_err() { - return Err(ApiError::err("community_follower_already_exists").into()); - } + blocking(context.pool(), unfollow) + .await? + .map_err(|e| ApiError::err("community_follower_already_exists", e))?; } } else if data.follow { // Dont actually add to the community followers here, because you need @@ -89,9 +89,9 @@ impl Perform for FollowCommunity { } else { UndoFollowCommunity::send(&local_user_view.person, &community, context).await?; let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form); - if blocking(context.pool(), unfollow).await?.is_err() { - return Err(ApiError::err("community_follower_already_exists").into()); - } + blocking(context.pool(), unfollow) + .await? + .map_err(|e| ApiError::err("community_follower_already_exists", e))?; } let community_id = data.community_id; @@ -134,9 +134,9 @@ impl Perform for BlockCommunity { if data.block { let block = move |conn: &'_ _| CommunityBlock::block(conn, &community_block_form); - if blocking(context.pool(), block).await?.is_err() { - return Err(ApiError::err("community_block_already_exists").into()); - } + blocking(context.pool(), block) + .await? + .map_err(|e| ApiError::err("community_block_already_exists", e))?; // Also, unfollow the community, and send a federated unfollow let community_follower_form = CommunityFollowerForm { @@ -156,9 +156,9 @@ impl Perform for BlockCommunity { UndoFollowCommunity::send(&local_user_view.person, &community, context).await?; } else { let unblock = move |conn: &'_ _| CommunityBlock::unblock(conn, &community_block_form); - if blocking(context.pool(), unblock).await?.is_err() { - return Err(ApiError::err("community_block_already_exists").into()); - } + blocking(context.pool(), unblock) + .await? + .map_err(|e| ApiError::err("community_block_already_exists", e))?; } let community_view = blocking(context.pool(), move |conn| { @@ -208,9 +208,9 @@ impl Perform for BanFromCommunity { if data.ban { let ban = move |conn: &'_ _| CommunityPersonBan::ban(conn, &community_user_ban_form); - if blocking(context.pool(), ban).await?.is_err() { - return Err(ApiError::err("community_user_already_banned").into()); - } + blocking(context.pool(), ban) + .await? + .map_err(|e| ApiError::err("community_user_already_banned", e))?; // Also unsubscribe them from the community, if they are subscribed let community_follower_form = CommunityFollowerForm { @@ -228,9 +228,9 @@ impl Perform for BanFromCommunity { .await?; } else { let unban = move |conn: &'_ _| CommunityPersonBan::unban(conn, &community_user_ban_form); - if blocking(context.pool(), unban).await?.is_err() { - return Err(ApiError::err("community_user_already_banned").into()); - } + blocking(context.pool(), unban) + .await? + .map_err(|e| ApiError::err("community_user_already_banned", e))?; UndoBlockUserFromCommunity::send( &community, &banned_person, @@ -332,14 +332,14 @@ impl Perform for AddModToCommunity { }; if data.added { let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); - if blocking(context.pool(), join).await?.is_err() { - return Err(ApiError::err("community_moderator_already_exists").into()); - } + blocking(context.pool(), join) + .await? + .map_err(|e| ApiError::err("community_moderator_already_exists", e))?; } else { let leave = move |conn: &'_ _| CommunityModerator::leave(conn, &community_moderator_form); - if blocking(context.pool(), leave).await?.is_err() { - return Err(ApiError::err("community_moderator_already_exists").into()); - } + blocking(context.pool(), leave) + .await? + .map_err(|e| ApiError::err("community_moderator_already_exists", e))?; } // Mod tables @@ -433,7 +433,7 @@ impl Perform for TransferCommunity { .map(|a| a.person.id) .any(|x| x == local_user_view.person.id) { - return Err(ApiError::err("not_an_admin").into()); + return Err(ApiError::err_plain("not_an_admin").into()); } // You have to re-do the community_moderator table, reordering it. @@ -461,9 +461,9 @@ impl Perform for TransferCommunity { }; let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); - if blocking(context.pool(), join).await?.is_err() { - return Err(ApiError::err("community_moderator_already_exists").into()); - } + blocking(context.pool(), join) + .await? + .map_err(|e| ApiError::err("community_moderator_already_exists", e))?; } // Mod tables @@ -484,14 +484,14 @@ impl Perform for TransferCommunity { CommunityView::read(conn, community_id, Some(person_id)) }) .await? - .map_err(|_| ApiError::err("couldnt_find_community"))?; + .map_err(|e| ApiError::err("couldnt_find_community", e))?; let community_id = data.community_id; let moderators = blocking(context.pool(), move |conn| { CommunityModeratorView::for_community(conn, community_id) }) .await? - .map_err(|_| ApiError::err("couldnt_find_community"))?; + .map_err(|e| ApiError::err("couldnt_find_community", e))?; // Return the jwt Ok(GetCommunityResponse { diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index ff732e6bb..a7d2f0c3c 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -88,7 +88,7 @@ impl Perform for Login { LocalUserView::find_by_email_or_name(conn, &username_or_email) }) .await? - .map_err(|_| ApiError::err("couldnt_find_that_username_or_email"))?; + .map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))?; // Verify the password let valid: bool = verify( @@ -97,7 +97,7 @@ impl Perform for Login { ) .unwrap_or(false); if !valid { - return Err(ApiError::err("password_incorrect").into()); + return Err(ApiError::err_plain("password_incorrect").into()); } // Return the jwt @@ -179,7 +179,7 @@ impl Perform for SaveUserSettings { if let Some(Some(bio)) = &bio { if bio.chars().count() > 300 { - return Err(ApiError::err("bio_length_overflow").into()); + return Err(ApiError::err_plain("bio_length_overflow").into()); } } @@ -188,13 +188,13 @@ impl Perform for SaveUserSettings { display_name.trim(), context.settings().actor_name_max_length, ) { - return Err(ApiError::err("invalid_username").into()); + return Err(ApiError::err_plain("invalid_username").into()); } } if let Some(Some(matrix_user_id)) = &matrix_user_id { if !is_valid_matrix_id(matrix_user_id) { - return Err(ApiError::err("invalid_matrix_id").into()); + return Err(ApiError::err_plain("invalid_matrix_id").into()); } } @@ -226,16 +226,11 @@ impl Perform for SaveUserSettings { bot_account, }; - let person_res = blocking(context.pool(), move |conn| { + blocking(context.pool(), move |conn| { Person::update(conn, person_id, &person_form) }) - .await?; - let _updated_person: Person = match person_res { - Ok(p) => p, - Err(_) => { - return Err(ApiError::err("user_already_exists").into()); - } - }; + .await? + .map_err(|e| ApiError::err("user_already_exists", e))?; let local_user_form = LocalUserForm { person_id, @@ -269,7 +264,7 @@ impl Perform for SaveUserSettings { "user_already_exists" }; - return Err(ApiError::err(err_type).into()); + return Err(ApiError::err(err_type, e).into()); } }; @@ -301,7 +296,7 @@ impl Perform for ChangePassword { // Make sure passwords match if data.new_password != data.new_password_verify { - return Err(ApiError::err("passwords_dont_match").into()); + return Err(ApiError::err_plain("passwords_dont_match").into()); } // Check the old password @@ -311,7 +306,7 @@ impl Perform for ChangePassword { ) .unwrap_or(false); if !valid { - return Err(ApiError::err("password_incorrect").into()); + return Err(ApiError::err_plain("password_incorrect").into()); } let local_user_id = local_user_view.local_user.id; @@ -350,16 +345,11 @@ impl Perform for AddAdmin { let added = data.added; let added_person_id = data.person_id; - let added_admin = match blocking(context.pool(), move |conn| { + let added_admin = blocking(context.pool(), move |conn| { Person::add_admin(conn, added_person_id, added) }) .await? - { - Ok(a) => a, - Err(_) => { - return Err(ApiError::err("couldnt_update_user").into()); - } - }; + .map_err(|e| ApiError::err("couldnt_update_user", e))?; // Mod tables let form = ModAddForm { @@ -414,9 +404,9 @@ impl Perform for BanPerson { let ban = data.ban; let banned_person_id = data.person_id; let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban); - if blocking(context.pool(), ban_person).await?.is_err() { - return Err(ApiError::err("couldnt_update_user").into()); - } + blocking(context.pool(), ban_person) + .await? + .map_err(|e| ApiError::err("couldnt_update_user", e))?; // Remove their data if that's desired if data.remove_data.unwrap_or(false) { @@ -506,7 +496,7 @@ impl Perform for BlockPerson { // Don't let a person block themselves if target_id == person_id { - return Err(ApiError::err("cant_block_yourself").into()); + return Err(ApiError::err_plain("cant_block_yourself").into()); } let person_block_form = PersonBlockForm { @@ -516,14 +506,14 @@ impl Perform for BlockPerson { if data.block { let block = move |conn: &'_ _| PersonBlock::block(conn, &person_block_form); - if blocking(context.pool(), block).await?.is_err() { - return Err(ApiError::err("person_block_already_exists").into()); - } + blocking(context.pool(), block) + .await? + .map_err(|e| ApiError::err("person_block_already_exists", e))?; } else { let unblock = move |conn: &'_ _| PersonBlock::unblock(conn, &person_block_form); - if blocking(context.pool(), unblock).await?.is_err() { - return Err(ApiError::err("person_block_already_exists").into()); - } + blocking(context.pool(), unblock) + .await? + .map_err(|e| ApiError::err("person_block_already_exists", e))?; } // TODO does any federated stuff need to be done here? @@ -635,16 +625,16 @@ impl Perform for MarkPersonMentionAsRead { .await??; if local_user_view.person.id != read_person_mention.recipient_id { - return Err(ApiError::err("couldnt_update_comment").into()); + return Err(ApiError::err_plain("couldnt_update_comment").into()); } let person_mention_id = read_person_mention.id; let read = data.read; let update_mention = move |conn: &'_ _| PersonMention::update_read(conn, person_mention_id, read); - if blocking(context.pool(), update_mention).await?.is_err() { - return Err(ApiError::err("couldnt_update_comment").into()); - }; + blocking(context.pool(), update_mention) + .await? + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; let person_mention_id = read_person_mention.id; let person_id = local_user_view.person.id; @@ -690,26 +680,23 @@ impl Perform for MarkAllAsRead { for comment_view in &replies { let reply_id = comment_view.comment.id; let mark_as_read = move |conn: &'_ _| Comment::update_read(conn, reply_id, true); - if blocking(context.pool(), mark_as_read).await?.is_err() { - return Err(ApiError::err("couldnt_update_comment").into()); - } + blocking(context.pool(), mark_as_read) + .await? + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; } // Mark all user mentions as read let update_person_mentions = move |conn: &'_ _| PersonMention::mark_all_as_read(conn, person_id); - if blocking(context.pool(), update_person_mentions) + blocking(context.pool(), update_person_mentions) .await? - .is_err() - { - return Err(ApiError::err("couldnt_update_comment").into()); - } + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; // Mark all private_messages as read let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, person_id); - if blocking(context.pool(), update_pm).await?.is_err() { - return Err(ApiError::err("couldnt_update_private_message").into()); - } + blocking(context.pool(), update_pm) + .await? + .map_err(|e| ApiError::err("couldnt_update_private_message", e))?; Ok(GetRepliesResponse { replies: vec![] }) } @@ -732,7 +719,7 @@ impl Perform for PasswordReset { LocalUserView::find_by_email(conn, &email) }) .await? - .map_err(|_| ApiError::err("couldnt_find_that_username_or_email"))?; + .map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))?; // Generate a random token let token = generate_random_string(); @@ -758,7 +745,7 @@ impl Perform for PasswordReset { html, &context.settings(), ) - .map_err(|e| ApiError::err(&e))?; + .map_err(|e| ApiError::err("email_send_failed", e))?; Ok(PasswordResetResponse {}) } @@ -786,7 +773,7 @@ impl Perform for PasswordChange { // Make sure passwords match if data.password != data.password_verify { - return Err(ApiError::err("passwords_dont_match").into()); + return Err(ApiError::err_plain("passwords_dont_match").into()); } // Update the user with the new password @@ -795,7 +782,7 @@ impl Perform for PasswordChange { LocalUser::update_password(conn, local_user_id, &password) }) .await? - .map_err(|_| ApiError::err("couldnt_update_user"))?; + .map_err(|e| ApiError::err("couldnt_update_user", e))?; // Return the jwt Ok(LoginResponse { diff --git a/crates/api/src/post.rs b/crates/api/src/post.rs index da828725d..d2440b7a3 100644 --- a/crates/api/src/post.rs +++ b/crates/api/src/post.rs @@ -73,9 +73,9 @@ impl Perform for CreatePostLike { if do_add { let like_form2 = like_form.clone(); let like = move |conn: &'_ _| PostLike::like(conn, &like_form2); - if blocking(context.pool(), like).await?.is_err() { - return Err(ApiError::err("couldnt_like_post").into()); - } + blocking(context.pool(), like) + .await? + .map_err(|e| ApiError::err("couldnt_like_post", e))?; Vote::send( &object, @@ -269,14 +269,14 @@ impl Perform for SavePost { if data.save { let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form); - if blocking(context.pool(), save).await?.is_err() { - return Err(ApiError::err("couldnt_save_post").into()); - } + blocking(context.pool(), save) + .await? + .map_err(|e| ApiError::err("couldnt_save_post", e))?; } else { let unsave = move |conn: &'_ _| PostSaved::unsave(conn, &post_saved_form); - if blocking(context.pool(), unsave).await?.is_err() { - return Err(ApiError::err("couldnt_save_post").into()); - } + blocking(context.pool(), unsave) + .await? + .map_err(|e| ApiError::err("couldnt_save_post", e))?; } let post_id = data.post_id; diff --git a/crates/api/src/post_report.rs b/crates/api/src/post_report.rs index 8f5c72afa..82f3c44a4 100644 --- a/crates/api/src/post_report.rs +++ b/crates/api/src/post_report.rs @@ -39,10 +39,10 @@ impl Perform for CreatePostReport { // check size of report and check for whitespace let reason = data.reason.trim(); if reason.is_empty() { - return Err(ApiError::err("report_reason_required").into()); + return Err(ApiError::err_plain("report_reason_required").into()); } if reason.chars().count() > 1000 { - return Err(ApiError::err("report_too_long").into()); + return Err(ApiError::err_plain("report_too_long").into()); } let person_id = local_user_view.person.id; @@ -67,7 +67,7 @@ impl Perform for CreatePostReport { PostReport::report(conn, &report_form) }) .await? - .map_err(|_| ApiError::err("couldnt_create_report"))?; + .map_err(|e| ApiError::err("couldnt_create_report", e))?; let post_report_view = blocking(context.pool(), move |conn| { PostReportView::read(conn, report.id, person_id) @@ -120,9 +120,9 @@ impl Perform for ResolvePostReport { } }; - if blocking(context.pool(), resolve_fun).await?.is_err() { - return Err(ApiError::err("couldnt_resolve_report").into()); - }; + blocking(context.pool(), resolve_fun) + .await? + .map_err(|e| ApiError::err("couldnt_resolve_report", e))?; let post_report_view = blocking(context.pool(), move |conn| { PostReportView::read(conn, report_id, person_id) diff --git a/crates/api/src/private_message.rs b/crates/api/src/private_message.rs index 31f6901dc..6be6ba05b 100644 --- a/crates/api/src/private_message.rs +++ b/crates/api/src/private_message.rs @@ -30,7 +30,7 @@ impl Perform for MarkPrivateMessageAsRead { }) .await??; if local_user_view.person.id != orig_private_message.recipient_id { - return Err(ApiError::err("couldnt_update_private_message").into()); + return Err(ApiError::err_plain("couldnt_update_private_message").into()); } // Doing the update @@ -40,7 +40,7 @@ impl Perform for MarkPrivateMessageAsRead { PrivateMessage::update_read(conn, private_message_id, read) }) .await? - .map_err(|_| ApiError::err("couldnt_update_private_message"))?; + .map_err(|e| ApiError::err("couldnt_update_private_message", e))?; // No need to send an apub update let op = UserOperation::MarkPrivateMessageAsRead; diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index a8d2e7338..a80dfe66c 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -389,10 +389,10 @@ impl Perform for ResolveObject { get_local_user_view_from_jwt_opt(&self.auth, context.pool(), context.secret()).await?; let res = search_by_apub_id(&self.q, context) .await - .map_err(|_| ApiError::err("couldnt_find_object"))?; + .map_err(|e| ApiError::err("couldnt_find_object", e))?; convert_response(res, local_user_view.map(|l| l.person.id), context.pool()) .await - .map_err(|_| ApiError::err("couldnt_find_object").into()) + .map_err(|e| ApiError::err("couldnt_find_object", e).into()) } } @@ -454,14 +454,14 @@ impl Perform for TransferSite { // Make sure user is the creator if read_site.creator_id != local_user_view.person.id { - return Err(ApiError::err("not_an_admin").into()); + return Err(ApiError::err_plain("not_an_admin").into()); } let new_creator_id = data.person_id; let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id); - if blocking(context.pool(), transfer_site).await?.is_err() { - return Err(ApiError::err("couldnt_update_site").into()); - }; + blocking(context.pool(), transfer_site) + .await? + .map_err(|e| ApiError::err("couldnt_update_site", e))?; // Mod tables let form = ModAddForm { @@ -542,7 +542,7 @@ impl Perform for SaveSiteConfig { // Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem let config_hjson = Settings::save_config_file(&data.config_hjson) - .map_err(|_| ApiError::err("couldnt_update_site"))?; + .map_err(|e| ApiError::err("couldnt_update_site", e))?; Ok(GetSiteConfigResponse { config_hjson }) } diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 068de48a1..07edab0f7 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -225,14 +225,14 @@ pub async fn is_mod_or_admin( }) .await?; if !is_mod_or_admin { - return Err(ApiError::err("not_a_mod_or_admin").into()); + return Err(ApiError::err_plain("not_a_mod_or_admin").into()); } Ok(()) } pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { if !local_user_view.person.admin { - return Err(ApiError::err("not_an_admin").into()); + return Err(ApiError::err_plain("not_an_admin").into()); } Ok(()) } @@ -240,7 +240,7 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result { blocking(pool, move |conn| Post::read(conn, post_id)) .await? - .map_err(|_| ApiError::err("couldnt_find_post").into()) + .map_err(|_| ApiError::err_plain("couldnt_find_post").into()) } pub async fn mark_post_as_read( @@ -254,7 +254,7 @@ pub async fn mark_post_as_read( PostRead::mark_as_read(conn, &post_read_form) }) .await? - .map_err(|_| ApiError::err("couldnt_mark_post_as_read").into()) + .map_err(|_| ApiError::err_plain("couldnt_mark_post_as_read").into()) } pub async fn get_local_user_view_from_jwt( @@ -263,19 +263,19 @@ pub async fn get_local_user_view_from_jwt( secret: &Secret, ) -> Result { let claims = Claims::decode(jwt, &secret.jwt_secret) - .map_err(|_| ApiError::err("not_logged_in"))? + .map_err(|e| ApiError::err("not_logged_in", e))? .claims; let local_user_id = LocalUserId(claims.sub); let local_user_view = blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??; // Check for a site ban if local_user_view.person.banned { - return Err(ApiError::err("site_ban").into()); + return Err(ApiError::err_plain("site_ban").into()); } // Check for user deletion if local_user_view.person.deleted { - return Err(ApiError::err("deleted").into()); + return Err(ApiError::err_plain("deleted").into()); } check_validator_time(&local_user_view.local_user.validator_time, &claims)?; @@ -290,7 +290,7 @@ pub fn check_validator_time( ) -> Result<(), LemmyError> { let user_validation_time = validator_time.timestamp(); if user_validation_time > claims.iat { - Err(ApiError::err("not_logged_in").into()) + Err(ApiError::err_plain("not_logged_in").into()) } else { Ok(()) } @@ -313,7 +313,7 @@ pub async fn get_local_user_settings_view_from_jwt( secret: &Secret, ) -> Result { let claims = Claims::decode(jwt, &secret.jwt_secret) - .map_err(|_| ApiError::err("not_logged_in"))? + .map_err(|e| ApiError::err("not_logged_in", e))? .claims; let local_user_id = LocalUserId(claims.sub); let local_user_view = blocking(pool, move |conn| { @@ -322,7 +322,7 @@ pub async fn get_local_user_settings_view_from_jwt( .await??; // Check for a site ban if local_user_view.person.banned { - return Err(ApiError::err("site_ban").into()); + return Err(ApiError::err_plain("site_ban").into()); } check_validator_time(&local_user_view.local_user.validator_time, &claims)?; @@ -351,7 +351,7 @@ pub async fn check_community_ban( let is_banned = move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok(); if blocking(pool, is_banned).await? { - Err(ApiError::err("community_ban").into()) + Err(ApiError::err_plain("community_ban").into()) } else { Ok(()) } @@ -364,7 +364,7 @@ pub async fn check_person_block( ) -> Result<(), LemmyError> { let is_blocked = move |conn: &'_ _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok(); if blocking(pool, is_blocked).await? { - Err(ApiError::err("person_block").into()) + Err(ApiError::err_plain("person_block").into()) } else { Ok(()) } @@ -374,7 +374,7 @@ pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), Le if score == -1 { let site = blocking(pool, move |conn| Site::read_simple(conn)).await??; if !site.enable_downvotes { - return Err(ApiError::err("downvotes_disabled").into()); + return Err(ApiError::err_plain("downvotes_disabled").into()); } } Ok(()) @@ -425,7 +425,7 @@ pub async fn build_federated_instances( /// Checks the password length pub fn password_length_check(pass: &str) -> Result<(), LemmyError> { if !(10..=60).contains(&pass.len()) { - Err(ApiError::err("invalid_password").into()) + Err(ApiError::err_plain("invalid_password").into()) } else { Ok(()) } @@ -434,7 +434,7 @@ pub fn password_length_check(pass: &str) -> Result<(), LemmyError> { /// Checks the site description length pub fn site_description_length_check(description: &str) -> Result<(), LemmyError> { if description.len() > 150 { - Err(ApiError::err("site_description_length_overflow").into()) + Err(ApiError::err_plain("site_description_length_overflow").into()) } else { Ok(()) } @@ -443,7 +443,7 @@ pub fn site_description_length_check(description: &str) -> Result<(), LemmyError /// Checks for a honeypot. If this field is filled, fail the rest of the function pub fn honeypot_check(honeypot: &Option) -> Result<(), LemmyError> { if honeypot.is_some() { - Err(ApiError::err("honeypot_fail").into()) + Err(ApiError::err_plain("honeypot_fail").into()) } else { Ok(()) } diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index c357e6047..674914629 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -61,7 +61,7 @@ impl PerformCrud for CreateComment { // Check if post is locked, no new comments if post.locked { - return Err(ApiError::err("locked").into()); + return Err(ApiError::err_plain("locked").into()); } // If there's a parent_id, check to make sure that comment is in that post @@ -69,13 +69,13 @@ impl PerformCrud for CreateComment { // Make sure the parent comment exists let parent = blocking(context.pool(), move |conn| Comment::read(conn, parent_id)) .await? - .map_err(|_| ApiError::err("couldnt_create_comment"))?; + .map_err(|e| ApiError::err("couldnt_create_comment", e))?; check_person_block(local_user_view.person.id, parent.creator_id, context.pool()).await?; // Strange issue where sometimes the post ID is incorrect if parent.post_id != post_id { - return Err(ApiError::err("couldnt_create_comment").into()); + return Err(ApiError::err_plain("couldnt_create_comment").into()); } } @@ -93,7 +93,7 @@ impl PerformCrud for CreateComment { Comment::create(conn, &comment_form2) }) .await? - .map_err(|_| ApiError::err("couldnt_create_comment"))?; + .map_err(|e| ApiError::err("couldnt_create_comment", e))?; // Necessary to update the ap_id let inserted_comment_id = inserted_comment.id; @@ -109,7 +109,7 @@ impl PerformCrud for CreateComment { Ok(Comment::update_ap_id(conn, inserted_comment_id, apub_id)?) }) .await? - .map_err(|_| ApiError::err("couldnt_create_comment"))?; + .map_err(|e| ApiError::err("couldnt_create_comment", e))?; CreateOrUpdateComment::send( &updated_comment, @@ -142,9 +142,9 @@ impl PerformCrud for CreateComment { }; let like = move |conn: &'_ _| CommentLike::like(conn, &like_form); - if blocking(context.pool(), like).await?.is_err() { - return Err(ApiError::err("couldnt_like_comment").into()); - } + blocking(context.pool(), like) + .await? + .map_err(|e| ApiError::err("couldnt_like_comment", e))?; let object = PostOrComment::Comment(updated_comment); Vote::send( @@ -170,7 +170,7 @@ impl PerformCrud for CreateComment { Comment::update_read(conn, comment_id, true) }) .await? - .map_err(|_| ApiError::err("couldnt_update_comment"))?; + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; } // If its a reply, mark the parent as read if let Some(parent_id) = data.parent_id { @@ -183,7 +183,7 @@ impl PerformCrud for CreateComment { Comment::update_read(conn, parent_id, true) }) .await? - .map_err(|_| ApiError::err("couldnt_update_parent_comment"))?; + .map_err(|e| ApiError::err("couldnt_update_parent_comment", e))?; } // If the parent has PersonMentions mark them as read too let person_id = local_user_view.person.id; @@ -196,7 +196,7 @@ impl PerformCrud for CreateComment { PersonMention::update_read(conn, mention.id, true) }) .await? - .map_err(|_| ApiError::err("couldnt_update_person_mentions"))?; + .map_err(|e| ApiError::err("couldnt_update_person_mentions", e))?; } } diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 0b44f4ebb..96e8063d8 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -43,7 +43,7 @@ impl PerformCrud for DeleteComment { // Verify that only the creator can delete if local_user_view.person.id != orig_comment.creator.id { - return Err(ApiError::err("no_comment_edit_allowed").into()); + return Err(ApiError::err_plain("no_comment_edit_allowed").into()); } // Do the delete @@ -52,7 +52,7 @@ impl PerformCrud for DeleteComment { Comment::update_deleted(conn, comment_id, deleted) }) .await? - .map_err(|_| ApiError::err("couldnt_update_comment"))?; + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; // Send the apub message let community = blocking(context.pool(), move |conn| { @@ -134,7 +134,7 @@ impl PerformCrud for RemoveComment { Comment::update_removed(conn, comment_id, removed) }) .await? - .map_err(|_| ApiError::err("couldnt_update_comment"))?; + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; // Mod tables let form = ModRemoveCommentForm { diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 8ee9eb628..c4d0c394b 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -51,7 +51,7 @@ impl PerformCrud for GetComments { .list() }) .await? - .map_err(|_| ApiError::err("couldnt_get_comments"))?; + .map_err(|e| ApiError::err("couldnt_get_comments", e))?; // Blank out deleted or removed info for cv in comments diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 24e2ddbdd..800e124d5 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -51,7 +51,7 @@ impl PerformCrud for EditComment { // Verify that only the creator can edit if local_user_view.person.id != orig_comment.creator.id { - return Err(ApiError::err("no_comment_edit_allowed").into()); + return Err(ApiError::err_plain("no_comment_edit_allowed").into()); } // Do the update @@ -62,7 +62,7 @@ impl PerformCrud for EditComment { Comment::update_content(conn, comment_id, &content_slurs_removed) }) .await? - .map_err(|_| ApiError::err("couldnt_update_comment"))?; + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; // Send the apub update CreateOrUpdateComment::send( diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index 2d1076f3b..56d04ce54 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -51,7 +51,7 @@ impl PerformCrud for CreateCommunity { let site = blocking(context.pool(), move |conn| Site::read(conn, 0)).await??; if site.community_creation_admin_only && is_admin(&local_user_view).is_err() { - return Err(ApiError::err("only_admins_can_create_communities").into()); + return Err(ApiError::err_plain("only_admins_can_create_communities").into()); } check_slurs(&data.name, &context.settings().slur_regex())?; @@ -59,7 +59,7 @@ impl PerformCrud for CreateCommunity { check_slurs_opt(&data.description, &context.settings().slur_regex())?; if !is_valid_actor_name(&data.name, context.settings().actor_name_max_length) { - return Err(ApiError::err("invalid_community_name").into()); + return Err(ApiError::err_plain("invalid_community_name").into()); } // Double check for duplicate community actor_ids @@ -71,7 +71,7 @@ impl PerformCrud for CreateCommunity { let community_actor_id_wrapped = ObjectId::::new(community_actor_id.clone()); let community_dupe = community_actor_id_wrapped.dereference_local(context).await; if community_dupe.is_ok() { - return Err(ApiError::err("community_already_exists").into()); + return Err(ApiError::err_plain("community_already_exists").into()); } // Check to make sure the icon and banners are urls @@ -101,7 +101,7 @@ impl PerformCrud for CreateCommunity { Community::create(conn, &community_form) }) .await? - .map_err(|_| ApiError::err("community_already_exists"))?; + .map_err(|e| ApiError::err("community_already_exists", e))?; // The community creator becomes a moderator let community_moderator_form = CommunityModeratorForm { @@ -111,7 +111,7 @@ impl PerformCrud for CreateCommunity { let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); if blocking(context.pool(), join).await?.is_err() { - return Err(ApiError::err("community_moderator_already_exists").into()); + return Err(ApiError::err_plain("community_moderator_already_exists").into()); } // Follow your own community @@ -123,7 +123,7 @@ impl PerformCrud for CreateCommunity { let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); if blocking(context.pool(), follow).await?.is_err() { - return Err(ApiError::err("community_follower_already_exists").into()); + return Err(ApiError::err_plain("community_follower_already_exists").into()); } let person_id = local_user_view.person.id; diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index 2d54ff52c..ea1890402 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -33,7 +33,7 @@ impl PerformCrud for DeleteCommunity { // Make sure deleter is the top mod if local_user_view.person.id != community_mods[0].moderator.id { - return Err(ApiError::err("no_community_edit_allowed").into()); + return Err(ApiError::err_plain("no_community_edit_allowed").into()); } // Do the delete @@ -43,7 +43,7 @@ impl PerformCrud for DeleteCommunity { Community::update_deleted(conn, community_id, deleted) }) .await? - .map_err(|_| ApiError::err("couldnt_update_community"))?; + .map_err(|e| ApiError::err("couldnt_update_community", e))?; // Send apub messages send_apub_delete( @@ -89,7 +89,7 @@ impl PerformCrud for RemoveCommunity { Community::update_removed(conn, community_id, removed) }) .await? - .map_err(|_| ApiError::err("couldnt_update_community"))?; + .map_err(|e| ApiError::err("couldnt_update_community", e))?; // Mod tables let expires = data.expires.map(naive_from_unix); diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 9008b71da..9d9bdce00 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -35,7 +35,7 @@ impl PerformCrud for GetCommunity { ObjectId::::new(community_actor_id) .dereference(context, &mut 0) .await - .map_err(|_| ApiError::err("couldnt_find_community"))? + .map_err(|e| ApiError::err("couldnt_find_community", e))? .id } }; @@ -44,7 +44,7 @@ impl PerformCrud for GetCommunity { CommunityView::read(conn, community_id, person_id) }) .await? - .map_err(|_| ApiError::err("couldnt_find_community"))?; + .map_err(|e| ApiError::err("couldnt_find_community", e))?; // Blank out deleted or removed info if community_view.community.deleted || community_view.community.removed { @@ -55,7 +55,7 @@ impl PerformCrud for GetCommunity { CommunityModeratorView::for_community(conn, community_id) }) .await? - .map_err(|_| ApiError::err("couldnt_find_community"))?; + .map_err(|e| ApiError::err("couldnt_find_community", e))?; let online = context .chat_server() diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index ef94ad595..56fe72838 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -40,7 +40,7 @@ impl PerformCrud for EditCommunity { }) .await??; if !mods.contains(&local_user_view.person.id) { - return Err(ApiError::err("not_a_moderator").into()); + return Err(ApiError::err_plain("not_a_moderator").into()); } let community_id = data.community_id; @@ -68,7 +68,7 @@ impl PerformCrud for EditCommunity { Community::update(conn, community_id, &community_form) }) .await? - .map_err(|_| ApiError::err("couldnt_update_community"))?; + .map_err(|e| ApiError::err("couldnt_update_community", e))?; UpdateCommunity::send(&updated_community, &local_user_view.person, context).await?; diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index 2b6b4b572..89e664631 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -50,7 +50,7 @@ impl PerformCrud for CreatePost { honeypot_check(&data.honeypot)?; if !is_valid_post_title(&data.name) { - return Err(ApiError::err("invalid_post_title").into()); + return Err(ApiError::err_plain("invalid_post_title").into()); } check_community_ban(local_user_view.person.id, data.community_id, context.pool()).await?; @@ -87,7 +87,7 @@ impl PerformCrud for CreatePost { "couldnt_create_post" }; - return Err(ApiError::err(err_type).into()); + return Err(ApiError::err(err_type, e).into()); } }; @@ -102,7 +102,7 @@ impl PerformCrud for CreatePost { Ok(Post::update_ap_id(conn, inserted_post_id, apub_id)?) }) .await? - .map_err(|_| ApiError::err("couldnt_create_post"))?; + .map_err(|e| ApiError::err("couldnt_create_post", e))?; CreateOrUpdatePost::send( &updated_post, @@ -123,7 +123,7 @@ impl PerformCrud for CreatePost { let like = move |conn: &'_ _| PostLike::like(conn, &like_form); if blocking(context.pool(), like).await?.is_err() { - return Err(ApiError::err("couldnt_like_post").into()); + return Err(ApiError::err_plain("couldnt_like_post").into()); } // Mark the post as read diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index 18ede8a37..f4086f39d 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -38,7 +38,7 @@ impl PerformCrud for DeletePost { // Verify that only the creator can delete if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) { - return Err(ApiError::err("no_post_edit_allowed").into()); + return Err(ApiError::err_plain("no_post_edit_allowed").into()); } // Update the post diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 1cfcbaf8c..76e9548ed 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -37,7 +37,7 @@ impl PerformCrud for GetPost { PostView::read(conn, id, person_id) }) .await? - .map_err(|_| ApiError::err("couldnt_find_post"))?; + .map_err(|e| ApiError::err("couldnt_find_post", e))?; // Blank out deleted info if post_view.post.deleted || post_view.post.removed { @@ -79,7 +79,7 @@ impl PerformCrud for GetPost { CommunityView::read(conn, community_id, person_id) }) .await? - .map_err(|_| ApiError::err("couldnt_find_community"))?; + .map_err(|e| ApiError::err("couldnt_find_community", e))?; // Blank out deleted or removed info if community_view.community.deleted || community_view.community.removed { @@ -155,7 +155,7 @@ impl PerformCrud for GetPosts { .list() }) .await? - .map_err(|_| ApiError::err("couldnt_get_posts"))?; + .map_err(|e| ApiError::err("couldnt_get_posts", e))?; // Blank out deleted or removed info for pv in posts diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index b94786826..9ccb2c052 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -32,7 +32,7 @@ impl PerformCrud for EditPost { if let Some(name) = &data.name { if !is_valid_post_title(name) { - return Err(ApiError::err("invalid_post_title").into()); + return Err(ApiError::err_plain("invalid_post_title").into()); } } @@ -48,7 +48,7 @@ impl PerformCrud for EditPost { // Verify that only the creator can edit if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) { - return Err(ApiError::err("no_post_edit_allowed").into()); + return Err(ApiError::err_plain("no_post_edit_allowed").into()); } // Fetch post links and Pictrs cached image @@ -88,7 +88,7 @@ impl PerformCrud for EditPost { "couldnt_update_post" }; - return Err(ApiError::err(err_type).into()); + return Err(ApiError::err(err_type, e).into()); } }; diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 10d77da45..d04412f60 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -52,8 +52,8 @@ impl PerformCrud for CreatePrivateMessage { .await? { Ok(private_message) => private_message, - Err(_e) => { - return Err(ApiError::err("couldnt_create_private_message").into()); + Err(e) => { + return Err(ApiError::err("couldnt_create_private_message", e).into()); } }; @@ -75,7 +75,7 @@ impl PerformCrud for CreatePrivateMessage { }, ) .await? - .map_err(|_| ApiError::err("couldnt_create_private_message"))?; + .map_err(|e| ApiError::err("couldnt_create_private_message", e))?; CreateOrUpdatePrivateMessage::send( &updated_private_message, diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 2171a1436..70efc903a 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -34,7 +34,7 @@ impl PerformCrud for DeletePrivateMessage { }) .await??; if local_user_view.person.id != orig_private_message.creator_id { - return Err(ApiError::err("no_private_message_edit_allowed").into()); + return Err(ApiError::err_plain("no_private_message_edit_allowed").into()); } // Doing the update @@ -44,7 +44,7 @@ impl PerformCrud for DeletePrivateMessage { PrivateMessage::update_deleted(conn, private_message_id, deleted) }) .await? - .map_err(|_| ApiError::err("couldnt_update_private_message"))?; + .map_err(|e| ApiError::err("couldnt_update_private_message", e))?; // Send the apub update if data.deleted { diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 1f7ec82ba..7ef2d71da 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -34,7 +34,7 @@ impl PerformCrud for EditPrivateMessage { }) .await??; if local_user_view.person.id != orig_private_message.creator_id { - return Err(ApiError::err("no_private_message_edit_allowed").into()); + return Err(ApiError::err_plain("no_private_message_edit_allowed").into()); } // Doing the update @@ -44,7 +44,7 @@ impl PerformCrud for EditPrivateMessage { PrivateMessage::update_content(conn, private_message_id, &content_slurs_removed) }) .await? - .map_err(|_| ApiError::err("couldnt_update_private_message"))?; + .map_err(|e| ApiError::err("couldnt_update_private_message", e))?; // Send the apub update CreateOrUpdatePrivateMessage::send( diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 658d4cf8f..7fdf4d3c8 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -36,7 +36,7 @@ impl PerformCrud for CreateSite { let read_site = move |conn: &'_ _| Site::read_simple(conn); if blocking(context.pool(), read_site).await?.is_ok() { - return Err(ApiError::err("site_already_exists").into()); + return Err(ApiError::err_plain("site_already_exists").into()); }; let local_user_view = @@ -73,7 +73,7 @@ impl PerformCrud for CreateSite { let create_site = move |conn: &'_ _| Site::create(conn, &site_form); if blocking(context.pool(), create_site).await?.is_err() { - return Err(ApiError::err("site_already_exists").into()); + return Err(ApiError::err_plain("site_already_exists").into()); } let site_view = blocking(context.pool(), SiteView::read).await??; diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index 88c6e6ea3..cfe492048 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -100,27 +100,27 @@ impl PerformCrud for GetSite { CommunityFollowerView::for_person(conn, person_id) }) .await? - .map_err(|_| ApiError::err("system_err_login"))?; + .map_err(|e| ApiError::err("system_err_login", e))?; let person_id = local_user_view.person.id; let community_blocks = blocking(context.pool(), move |conn| { CommunityBlockView::for_person(conn, person_id) }) .await? - .map_err(|_| ApiError::err("system_err_login"))?; + .map_err(|e| ApiError::err("system_err_login", e))?; let person_id = local_user_view.person.id; let person_blocks = blocking(context.pool(), move |conn| { PersonBlockView::for_person(conn, person_id) }) .await? - .map_err(|_| ApiError::err("system_err_login"))?; + .map_err(|e| ApiError::err("system_err_login", e))?; let moderates = blocking(context.pool(), move |conn| { CommunityModeratorView::for_person(conn, person_id) }) .await? - .map_err(|_| ApiError::err("system_err_login"))?; + .map_err(|e| ApiError::err("system_err_login", e))?; Some(MyUserInfo { local_user_view, diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 2190d02c3..192fa669f 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -65,9 +65,9 @@ impl PerformCrud for EditSite { }; let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form); - if blocking(context.pool(), update_site).await?.is_err() { - return Err(ApiError::err("couldnt_update_site").into()); - } + blocking(context.pool(), update_site) + .await? + .map_err(|e| ApiError::err("couldnt_update_site", e))?; let site_view = blocking(context.pool(), SiteView::read).await??; diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 2e855fff6..b2beeb8ed 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -50,7 +50,7 @@ impl PerformCrud for Register { // Make sure site has open registration if let Ok(site) = blocking(context.pool(), move |conn| Site::read_simple(conn)).await? { if !site.open_registration { - return Err(ApiError::err("registration_closed").into()); + return Err(ApiError::err_plain("registration_closed").into()); } } @@ -59,7 +59,7 @@ impl PerformCrud for Register { // Make sure passwords match if data.password != data.password_verify { - return Err(ApiError::err("passwords_dont_match").into()); + return Err(ApiError::err_plain("passwords_dont_match").into()); } // Check if there are admins. False if admins exist @@ -84,7 +84,7 @@ impl PerformCrud for Register { }) .await?; if !check { - return Err(ApiError::err("captcha_incorrect").into()); + return Err(ApiError::err_plain("captcha_incorrect").into()); } } @@ -92,7 +92,7 @@ impl PerformCrud for Register { let actor_keypair = generate_actor_keypair()?; if !is_valid_actor_name(&data.username, context.settings().actor_name_max_length) { - return Err(ApiError::err("invalid_username").into()); + return Err(ApiError::err_plain("invalid_username").into()); } let actor_id = generate_apub_endpoint( EndpointType::Person, @@ -119,7 +119,7 @@ impl PerformCrud for Register { Person::create(conn, &person_form) }) .await? - .map_err(|_| ApiError::err("user_already_exists"))?; + .map_err(|e| ApiError::err("user_already_exists", e))?; // Create the local user // TODO some of these could probably use the DB defaults @@ -161,7 +161,7 @@ impl PerformCrud for Register { }) .await??; - return Err(ApiError::err(err_type).into()); + return Err(ApiError::err(err_type, e).into()); } }; @@ -209,9 +209,9 @@ impl PerformCrud for Register { }; let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); - if blocking(context.pool(), follow).await?.is_err() { - return Err(ApiError::err("community_follower_already_exists").into()); - }; + blocking(context.pool(), follow) + .await? + .map_err(|e| ApiError::err("community_follower_already_exists", e))?; // If its an admin, add them as a mod and follower to main if no_admins { @@ -221,9 +221,9 @@ impl PerformCrud for Register { }; let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); - if blocking(context.pool(), join).await?.is_err() { - return Err(ApiError::err("community_moderator_already_exists").into()); - } + blocking(context.pool(), join) + .await? + .map_err(|e| ApiError::err("community_moderator_already_exists", e))?; } // Return the jwt diff --git a/crates/api_crud/src/user/delete.rs b/crates/api_crud/src/user/delete.rs index 24f3c4003..050f54116 100644 --- a/crates/api_crud/src/user/delete.rs +++ b/crates/api_crud/src/user/delete.rs @@ -27,21 +27,21 @@ impl PerformCrud for DeleteAccount { ) .unwrap_or(false); if !valid { - return Err(ApiError::err("password_incorrect").into()); + return Err(ApiError::err_plain("password_incorrect").into()); } // Comments let person_id = local_user_view.person.id; let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id); - if blocking(context.pool(), permadelete).await?.is_err() { - return Err(ApiError::err("couldnt_update_comment").into()); - } + blocking(context.pool(), permadelete) + .await? + .map_err(|e| ApiError::err("couldnt_update_comment", e))?; // Posts let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id); - if blocking(context.pool(), permadelete).await?.is_err() { - return Err(ApiError::err("couldnt_update_post").into()); - } + blocking(context.pool(), permadelete) + .await? + .map_err(|e| ApiError::err("couldnt_update_post", e))?; blocking(context.pool(), move |conn| { Person::delete_account(conn, person_id) diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index ea0090c23..7082d5231 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -49,7 +49,7 @@ impl PerformCrud for GetPersonDetails { .dereference(context, &mut 0) .await; person - .map_err(|_| ApiError::err("couldnt_find_that_username_or_email"))? + .map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))? .id } }; diff --git a/crates/db_queries/src/lib.rs b/crates/db_queries/src/lib.rs index 6ca502397..aa3c06da1 100644 --- a/crates/db_queries/src/lib.rs +++ b/crates/db_queries/src/lib.rs @@ -265,7 +265,7 @@ pub fn diesel_option_overwrite_to_url( Some("") => Ok(Some(None)), Some(str_url) => match Url::parse(str_url) { Ok(url) => Ok(Some(Some(url.into()))), - Err(_) => Err(ApiError::err("invalid_url")), + Err(e) => Err(ApiError::err("invalid_url", e)), }, None => Ok(None), } diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index ad539f8b0..057e067e6 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -18,8 +18,8 @@ pub mod utils; pub mod version; use http::StatusCode; - -use std::fmt; +use log::warn; +use std::{fmt, fmt::Display}; use thiserror::Error; pub type ConnectionId = usize; @@ -48,11 +48,17 @@ macro_rules! location_info { #[derive(Debug, Error)] #[error("{{\"error\":\"{message}\"}}")] pub struct ApiError { - pub message: String, + message: String, } impl ApiError { - pub fn err(msg: &str) -> Self { + pub fn err_plain(msg: &str) -> Self { + ApiError { + message: msg.to_string(), + } + } + pub fn err(msg: &str, original_error: E) -> Self { + warn!("{}", original_error); ApiError { message: msg.to_string(), } @@ -73,7 +79,7 @@ where } } -impl std::fmt::Display for LemmyError { +impl Display for LemmyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { self.inner.fmt(f) } diff --git a/crates/utils/src/utils.rs b/crates/utils/src/utils.rs index 97384fc2f..96dc340e4 100644 --- a/crates/utils/src/utils.rs +++ b/crates/utils/src/utils.rs @@ -47,11 +47,8 @@ pub(crate) fn slur_check<'a>(test: &'a str, slur_regex: &'a Regex) -> Result<(), } pub fn check_slurs(text: &str, slur_regex: &Regex) -> Result<(), ApiError> { - if let Err(slurs) = slur_check(text, slur_regex) { - Err(ApiError::err(&slurs_vec_to_str(slurs))) - } else { - Ok(()) - } + slur_check(text, slur_regex) + .map_err(|slurs| ApiError::err_plain(&slurs_vec_to_str(slurs.clone()))) } pub fn check_slurs_opt(text: &Option, slur_regex: &Regex) -> Result<(), ApiError> { diff --git a/crates/websocket/src/chat_server.rs b/crates/websocket/src/chat_server.rs index 7ab65aad2..db09ac95e 100644 --- a/crates/websocket/src/chat_server.rs +++ b/crates/websocket/src/chat_server.rs @@ -472,9 +472,9 @@ impl ChatServer { async move { let json: Value = serde_json::from_str(&msg.msg)?; let data = &json["data"].to_string(); - let op = &json["op"].as_str().ok_or(ApiError { - message: "Unknown op type".to_string(), - })?; + let op = &json["op"] + .as_str() + .ok_or_else(|| ApiError::err_plain("missing op"))?; if let Ok(user_operation_crud) = UserOperationCrud::from_str(op) { let fut = (message_handler_crud)(context, msg.id, user_operation_crud.clone(), data);