Dont swallow API errors (fixes #1834) (#1837)
authorNutomic <me@nutomic.com>
Wed, 13 Oct 2021 19:50:21 +0000 (19:50 +0000)
committerGitHub <noreply@github.com>
Wed, 13 Oct 2021 19:50:21 +0000 (15:50 -0400)
Dont swallow API errors (fixes #1834)

34 files changed:
crates/api/src/comment.rs
crates/api/src/comment_report.rs
crates/api/src/community.rs
crates/api/src/local_user.rs
crates/api/src/post.rs
crates/api/src/post_report.rs
crates/api/src/private_message.rs
crates/api/src/site.rs
crates/api_common/src/lib.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/delete.rs
crates/api_crud/src/comment/read.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/community/create.rs
crates/api_crud/src/community/delete.rs
crates/api_crud/src/community/read.rs
crates/api_crud/src/community/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/post/read.rs
crates/api_crud/src/post/update.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/delete.rs
crates/api_crud/src/private_message/update.rs
crates/api_crud/src/site/create.rs
crates/api_crud/src/site/read.rs
crates/api_crud/src/site/update.rs
crates/api_crud/src/user/create.rs
crates/api_crud/src/user/delete.rs
crates/api_crud/src/user/read.rs
crates/db_queries/src/lib.rs
crates/utils/src/lib.rs
crates/utils/src/utils.rs
crates/websocket/src/chat_server.rs

index 951bd395fca60eac48777d4a0f333cba04ee2114..9311d7dc25d82f4cc134c67a8311e6380aefd4bf 100644 (file)
@@ -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,
index 67bc42acc00fc16e3d830e51b3f94f111070207c..d12b8d6f2762ec5387ce9096998f9e5052794f0e 100644 (file)
@@ -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| {
index f4548be6dec35485ed2e269da6cd500e63361890..7a5e622ca9d337aaf440cfd8d5a40c0bd113e1ef 100644 (file)
@@ -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 {
index ff732e6bbfcfc2107a95a66c407759b01de6a2c4..a7d2f0c3cf8f1d86357b4d57d30e9921e970f793 100644 (file)
@@ -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 {
index da828725dbe3e327ce07d2ab4ce129879d0bb670..d2440b7a38a9f149bbdb4222f1ffe82c753bcc55 100644 (file)
@@ -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;
index 8f5c72afa5e0ec0a1713758231f081434eeeae2c..82f3c44a4e190dc2f9d0043484db7bc2d4b16113 100644 (file)
@@ -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)
index 31f6901dc8ef46ad74cc22ba12f2f8360b1236be..6be6ba05b19d05a5e45ec5c71617c9df89ce92d8 100644 (file)
@@ -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;
index a8d2e73381ab8dccc2aa17513d3811e4d63d1a8a..a80dfe66c8db94a71a026a14ccb604689ff0ee93 100644 (file)
@@ -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 })
   }
index 068de48a173705352d260892bb3a37011b648a43..07edab0f7240fc9d267edcb50a447a9d60d19ca3 100644 (file)
@@ -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<Post, LemmyError> {
   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<LocalUserView, LemmyError> {
   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<LocalUserSettingsView, LemmyError> {
   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<String>) -> Result<(), LemmyError> {
   if honeypot.is_some() {
-    Err(ApiError::err("honeypot_fail").into())
+    Err(ApiError::err_plain("honeypot_fail").into())
   } else {
     Ok(())
   }
index c357e60474827dde2641f941ea2a5771fd579181..674914629a6f0b483eb0f202c85a5f109b7f2273 100644 (file)
@@ -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))?;
       }
     }
 
index 0b44f4ebbd5e268bb91b5802cfc1860c2a5629d9..96e8063d8b63fdfc3aaadfc18058bac2eefbca36 100644 (file)
@@ -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 {
index 8ee9eb62860737f7ee622261f802be9927ff41eb..c4d0c394b7f1b82c3a017409f29bdf8f63827a25 100644 (file)
@@ -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
index 24e2ddbdd2ae0ae3ba64232027044b6e0a13f240..800e124d5bb8f8f23c55f1204f87a5bd61b0781a 100644 (file)
@@ -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(
index 2d1076f3b64e391758470f0b32ab9469fa9ca37d..56d04ce541a1d9d4d481620d804827ac812a7b78 100644 (file)
@@ -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::<Community>::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;
index 2d54ff52c6bc89f6a0f7bc937839a7190a45c796..ea1890402ae88988ea42d0e474243147b4de10c3 100644 (file)
@@ -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);
index 9008b71da583e794a5748d928c7d22c8f7f66d5b..9d9bdce00f4f246afc64f33316151eda259ad1fc 100644 (file)
@@ -35,7 +35,7 @@ impl PerformCrud for GetCommunity {
         ObjectId::<Community>::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()
index ef94ad595e4f197c43ac079a9fbdb10707cafbd3..56fe72838a096ea1ada90516202343db718a9718 100644 (file)
@@ -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?;
 
index 2b6b4b572aa4e5889e8ff32ca0a5c2f4106f6071..89e664631e215790b2bc7abc37777e7fe7b0b53c 100644 (file)
@@ -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
index 18ede8a3743deab835154e7597d515775fa645a9..f4086f39d3ff98eb4377f8e8e6f9340780f44b2d 100644 (file)
@@ -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
index 1cfcbaf8c5f987300196530270da255274aae211..76e9548edd0628163ac154e2acae06231e47643c 100644 (file)
@@ -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
index b947868262fcd93403c8a5df496daf3fd916999c..9ccb2c052b4b607c57f7926185fa77e3a3db75ee 100644 (file)
@@ -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());
       }
     };
 
index 10d77da450c0015388b18689a815d2890ad7cb99..d04412f60f3b600bd0447973411367a6e8b4b5e5 100644 (file)
@@ -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,
index 2171a143622d2cd2442a059445dd4ab5f5311774..70efc903a6b9f213fe4607978d80d5db3c3a8a6a 100644 (file)
@@ -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 {
index 1f7ec82baa82e4e759cfc01ed33767b772f69123..7ef2d71da05df30ceb9014f19c4e05295a7ecf76 100644 (file)
@@ -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(
index 658d4cf8f2733f391ecf937c5b9e826b3c0cfdc6..7fdf4d3c836367e119546442dbe8bce19f8fe779 100644 (file)
@@ -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??;
index 88c6e6ea3e157b6f50b72a3e2c9e946803d8c281..cfe4920485d2bf86d5e45abf61392a920677e9d1 100644 (file)
@@ -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,
index 2190d02c32aa658cc9d307068b22ebc390c1a770..192fa669fb260de0bb228f1c3c9931a9613531cb 100644 (file)
@@ -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??;
 
index 2e855fff63e99aabc1e71b319fa97922e3c4320c..b2beeb8ed68e1951d824ce2184368d0f4feb4723 100644 (file)
@@ -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
index 24f3c4003f07d6ad106f3e8cbf594010bf061c52..050f54116c7e3ade4383721c3c174c60b292c9ed 100644 (file)
@@ -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)
index ea0090c234c07af858608c3f2a7bf0e0e735ebb4..7082d5231279d06d52ed8f892958df77f4f9ce21 100644 (file)
@@ -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
       }
     };
index 6ca502397599590bada15aad3aede16fd2a54076..aa3c06da14b253a858ab89ab5def98aca8893eb1 100644 (file)
@@ -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),
   }
index ad539f8b006c32d78d9955270a8c8ed5ee369c03..057e067e62a1d6db7a84e9ac578052fa2a737e2f 100644 (file)
@@ -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<E: Display>(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)
   }
index 97384fc2f19d0076706209bf4ce3e5b40b213901..96dc340e4e1d3be811d3a3f8b2ebffc4ed64cb5d 100644 (file)
@@ -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<String>, slur_regex: &Regex) -> Result<(), ApiError> {
index 7ab65aad23e20b4444040a7ca4e9148ea473ee3c..db09ac95ee7eb64c5e791e7e2a4b8bbce19a2e6b 100644 (file)
@@ -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);