Add test for unused errors, move federation errors into separate struct (#5024)

* Add test case to ensure all errors are in use

* Add test case to find errors that are only used for federation

* Move federation errors into separate enum (fixes #4926)

* clippy

* clippy

* remove serde tag

* Reduce errors dess (#5138)

* Add option to search exclusively by post title (#5015)

* Add option to search exclusively by post title

* Address format issues

* Remove duplicated 'removed' filter

* Replace url_search with search_term

* Build generic PostQuery before search match

* Create default queries. Move title_only to Search struct. Rename Url to PostURL

* Revert PostUrl to Url

* Upgrading webmention to 0.6.0, removes native-tls (#4976)

* Removing embedded pict-rs. (#5023)

Some reasons for removing this:

- Even as an optional dependency, it locks us to many specific versions
  of rust deps.
- Pict-rs is a large app that can and should be run in on its own.
- Violates the philosophy of separation of concerns.

* Adding clearurls crate to clean tracking params from links and markdown. (#5018)

* Adding clearurls crate to clean tracking params from links and markdown.

- Thanks to @jenrdikw for creating this
- Fixes #4905

* Upgrading to new version of clearurls

* Fix clippy

* Remove enable nsfw (#5017)

* Remove `local_site.enable_nsfw` in favor of `site.content_warning` (fixes #4627)

* cleanup usage of SiteView::read_local

* test

* uppercase

* SSO Support (#4881)

* Added OAUTH2 OIDC support

* Fixes and improvements based on review feedback

* use derive_new::new instead of TypedBuilder

* merge migrations into a single file

* fixes based on review feedback

* remove unnecessary hostname_ui config

* improvement based on review feedback

* improvements based on review feedback

* delete user oauth accounts at account deletion

* fixes and improvements based on review feedback

* removed auto_approve_application

* support registration application with sso

* improvements based on review feedback

* making the TokenResponse an internal struct as it should be

* remove duplicate struct

* prevent oauth linking to unverified accounts

* switched to manually entered username and removed the oauth name claim

* fix cargo fmt

* fix compile error

* improvements based on review feedback

* fixes and improvements based on review feedback

---------

Co-authored-by: privacyguard <privacyguard@users.noreply.github.com>

* Adding ability to restore content on user unban. (#4845)

* Adding ability to restore content on user unban.

- Fixes #4721

* Fixing api tests.

* Fix package.json

* Fixing lemmy-js-client dep.

* Adding API test for restoring content.

* Adding a default_comment_sort_type column for local_site and local_user. (#4469)

* Adding a default_comment_sort_type column for local_site and local_user.

- Renamed SortType to PostSortType in the DB and code.
- Renamed references to default_sort_type to default_post_sort_type.
- Fixes #4128

* Renaming migration to current date.

* Simplifying PostSortType.

* Simplify tests using default (#5026)

* Feature/custom emoji and tagline views (#4580)

* Add custom_emoji list route

* Add tagline list route

* Apply linting

* Remove unecessary TaglineView

* Add category filter for custom emoji

* Add create tagline endpoint

* Add update tagline endpoint

* Add delete tagline endpoint

* Format through lint.sh

* Remove custom_emojis and taglines from site resource

* Get random tagline on site requets

* Impl Crud for Tagline

Remove superfluous properties

* Move tagline endpoints under /admin

* Impl Crud for CustomEmoji

* Remove delete from tagline and custom emoji impls

* Check  markdown for tagline

* Validate markdown on tagline

* Make content fields non optional

Add error types for tagline validation

* Use process_markdown instead of process_markdown_opt

* Consolidate Tagline error types

* Remove unecessary clone

* Updat misleading comments

* Remove local_site_id from tagline and custom_emoji

* Update TaglineInserForm and TaglineUpdateForm

* Add ignore_page_limits for custom emojis

EmojiPicker needs to be able to retrieve all emojis in 1 call

* Update custom_emoji_view

Only keep get_all als helper function calling list with paging ignored

Only order on category when filtering on category

* Removing pointless get_all fn.

* remove tagline length checks

* make fields of TaglineInsertForm and TaglineUpdateForm mandatory

* move emoji order statement

* add comment for GetSiteResponse.tagline

---------

Co-authored-by: Freakazoid182 <>
Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: Dessalines <tyhou13@gmx.com>
Co-authored-by: Felix Ableitner <me@nutomic.com>

* Add category to RSS feeds (fixes #3446) (#5030)

* Unittest for Search by title only (#5033)

* added test for search by title only

* formatted rust files

* Upgrading to rust 1.81 (#5032)

* Remove TypedBuilder in favor of derive_new (fixes #4863) (#5020)

* Remove TypedBuilder in favor of derive_new (fixes #4863)

* fix

* fix

* Ignore zero values when setting rate limits (fixes #4280) (#5029)

* Ignore zero values when setting rate limits (fixes #4280)

Havent bothered to add an error message for such an uncommon case.

* fmt

* reorder, add test

* Always save remote image data (#4875)

* Always save remote image data

* cleanup

---------

Co-authored-by: Felix Ableitner <me@nutomic.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>

* Get rid of a lot of pointless mut form initializations. (#5037)

* Get rid of a lot of pointless mut form initializations.

- Fixes #5036

* Fix clippy.

* Simplify handling of NotFound SQL errors (fixes #4633) (#5031)

* Simplify handling of NotFound SQL errors (fixes #4633)

* fmt

* wip

* compiling

* clippy

* api tests

* fix

* Adding saved_only, liked_only, and disliked_only filters to search. (#5034)

* Adding saved_only, liked_only, and disliked_only filters to search.

- Fixes #4547

* Removing duplicate Url return type for search (was actually post).

- This now works like the post_title_only filter.

* Address PR comments.

* Add saved_only post_view test.

* Removing a few more Result<bool> . (#4977)

* Removing a few more Result<bool> .

* Running taplo fmt.

* Running fmt.

* Adding email taken test.

* Fixing tests.

* Adding back in missing admin check.

* Rename check_has_local_followers function.

* Conditionally hide comments on nsfw posts (fixes #4237) (#5028)

* Conditionally hide comments on nsfw posts (fixes #4237)

* fix test

* Post scheduling (fixes #234) (#5025)

* Post scheduling (fixes #234)

* clippy

* replace map_err with inspect_err

* ignore unpublished posts in read queries

* add api test

* fmt

* add some checks

* address some review comments

* allow updating schedule time

* rewrite scheduled task

* fmt

* machete

* compare date in sql, more filters

* check for community ban in sql

* remove api test (scheduled task only runs every 10 mins)

* remove mut

* add index

* remove Post::read impl

* fmt

* fix

* correctly handle changes to schedule time

* normal users can only schedule up to 10 posts

* Remove redundant local_user.auto_expand setting. (#5041)

- Fixes #4643

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

* Add ability to search for Community by its description (or title only). (#5044)

- This changes the post_title_only for Search to title_only, since its
  also used in the community query now.
- Fixes #4785

* Cleanup remaining use of Result<bool, Error> (fixes #4862) (#5047)

* Replace clippy allow annotation with expect (fixes #5012) (#5048)

* Add skip_serialize_none to OAuth structs with option fields (#5046)

* Add skip_serialize_none to OAuth structs with option fields

* PR feedback

* Remove serde and ts export from SSO db-only structs

* Apply scheduled post limit to future posts instead of past posts, and verify this in test (#5054)

* test scheduled_post_count

* fix syntax error

* fix formatting

* fix argument order

* fix user_scheduled_post_count function

* Avoid breaking changes, keep response fields as deprecated (#5058)

* Adding skip_serializing_none to another OAuth API request. (#5060)

* Handle partial settings backup (fixes #4307) (#5063)

* Handle partial settings backup (fixes #4307)

* clippy

* Avoid stack overflow when fetching nested comments, reduce max comment depth to 50 (#5009)

* Avoid stack overflow when fetching deeply nested comments

* add test case

* reduce comment depth, add docs

* decrease

* reduce max comment depth to 50

* fmt

* clippy

* cleanup

* Update Rust crate clap to v4.5.18 (#5066)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate reqwest to v0.12.8 (#5068)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate sitemap-rs to v0.2.2 (#5069)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate tracing-actix-web to v0.7.13 (#5070)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Changing renovate to run on the weekends. (#5067)

- Lemmy builds take a long time, and the current schedule only runs for
  about 4 hours once a month, and renovate also rate-limits itself to
  ~ 2 per hour. This gives it a large enough window, without clogging
  up my runner machines.

* Update Rust crate async-trait to v0.1.83 (#5065)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency @types/jest to v29.5.13 (#5071)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Attempt to fix test for fetching deeply nested comment (#5072)

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>

* Add modlog entries for bulk removals. (#5050)

* Add modlog entries for bulk removals.

- Added unit tests for removal / restore to api_common/utils.
- Fixes #4699

* Address PR comments.

* Combining remove and restore functions.

* Trigger build.

* Trigger build 2.

* Changing allow to expect.

* Adding local site settings to reject federated upvotes or downvotes. (#5038)

* Adding local site settings to reject federated upvotes or downvotes.

- Should help defend against downvote spamming instances.
- Fixes #4086

* Adding new vote mode types.

* Simpler activitypub vote check.

* Adding undo vote for failed vote mode check.

* Update crates/api_common/src/utils.rs

---------

Co-authored-by: Nutomic <me@nutomic.com>

* Replace `clippy::unwrap_used` in tests (#5064)

* Add LemmyResult to session_middleware tests

* Add LemmyResult to inboxes tests

* Add LemmyResult to slurs tests

* Add LemmyResult to markdown tests

* Add LemmyResult to rate_limiter tests

* Add LemmyResult to error tests

* Add LemmyResult to api_common utils tests

* Add LemmyResult to request tests

* Add LemmyResult to claims tests

* Propagate registration_applications errors

* Remove clippy::unwrap_used from community tests

* Add LemmyResult to community_view tests

* Add LemmyResult to db_schema post tests

* Add LemmyResult to site_aggregates tests

* Add LemmyResult to private_message tests

* Add LemmyResult to activity tests

* Add LemmyResult to federation_allowlist tests

* Add LemmyResult to comment_aggregates tests

* Add LemmyResult to post_report tests

* Add LemmyResult to moderator tests

* Add LemmyResult to community_aggregates tests

* Add LemmyResult to person_aggregates tests

* Add LemmyResult to language tests

* Add LemmyResult to post_aggregates tests

* Add LemmyResult to db_schema comment tests

* Add LemmyResult to actor_language tests

* Add LemmyResult to vote_view tests

* Add LemmyResult to registration_application_view tests

* Add LemmyResult to private_message_view tests

* Add LemmyResult to private_message_report_view tests

* Add LemmyResult to post_report_view tests

* Add LemmyResult to comment_report_view tests

* Add LemmyResult to sitemap tests

* Replace .expect() with .unwrap()

* Format code

* Remove clippy::unwrap_used from activity tests

* Add diesel result in db_schema tests

* Format code

* Map to_bytes() error to LemmyErrorType

* Remove clippy::unwrap_used from error tests

* Removing a few more unwraps, and cleaning up language code.

* Replace map_err with unwrap_or_default

* Replace ok_or with and_then

---------

Co-authored-by: Dessalines <tyhou13@gmx.com>

* Adding a get_random_community endpoint. (#5042)

* Adding a get_random_community endpoint.

- Fixes #4698

* Fixing issue from main.

* Adding ListingType to the query.

* More concise query filter.

* Resolve links to remote posts into local URL (#5057)

* move code to new file

* rewrite markdown links (fixes #2987)

* add missing file

* add helper fn

* also convert post.url

* simplify search.rs

* clippy

* also rewrite user/community links in markdown

* Call from apub handlers, cleanup

* no network requests in test

* clippy

* fix tests

* serial

* test

* no mut

* add api test

* fix api test

* Update Rust crate clap to v4.5.19 (#5080)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate html2text to v0.12.6 (#5081)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate rustls to v0.23.14 (#5083)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update rust-futures monorepo to v0.3.31 (#5090)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate actix-web-prom to 0.9.0 (#5091)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate regex to v1.11.0 (#5093)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate serde_with to v3.10.0 (#5094)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate serde_with to v3.11.0 (#5095)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency ts-jest to v29.2.5 (#5089)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency typescript to v5.6.2 (#5098)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency eslint to v9.12.0 (#5097)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update docker/dockerfile Docker tag to v1.10 (#5099)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update pnpm to v9.12.0 (#5100)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update Rust crate reqwest to v0.12.8 (#5082)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency @types/node to v22.7.4 (#5096)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update tamasfe/taplo Docker tag to v0.9.3 (#5101)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update tmknom/prettier Docker tag to v3.2.5 (#5102)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Add test case for community.hidden in post_view (ref #5074) (#5106)

* Resize post thumbnails (fixes #4053) (#5107)

* Resize post thumbnails (fixes #4053)

* 256px

* Update typescript-eslint monorepo to v8.8.1 (#5103)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update renovate config (#5109)

* Update renovate config

* ignroe rust updates, run on first day of month

* fix

* Add community alphabetic sorting (#5056)

* Started

* Finished? Need to write tests

* Formatting

* Formatting

* Formatting

* Write tests

* Formatting

* Formatting

* Formatting

* Unnecessary lifetime

* Safety

* Unwrap

* Formatting

* Formatting

* Fix local_only test

* Formatting

* Name consistency

* Adding lower to community name sort.

---------

Co-authored-by: Dessalines <tyhou13@gmx.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>

* Support markdown sub/superscript, use external crate for spoilers (#5135)

* Use external crate for spoiler tags

* Also add other plugins

* fix test

* Remove comment_like.post_id column which is unnecessary (ref #5122) (#5134)

* Allow admins to resolve removed or deleted objects via API (#5061)

* Allow admins to resolve removed or deleted objects via API

* Removing pointless TestUser.

---------

Co-authored-by: Dessalines <tyhou13@gmx.com>

* Remove individual user/community inboxes (#5124)

* Remove endpoints for individual community/user inboxes

fixes #4147
fixes #3928

* Remove shared_inbox_url columns

* fmt

* Fixing errors.

---------

Co-authored-by: Carlos Cabello <carloscabello364@gmail.com>
Co-authored-by: Nutomic <me@nutomic.com>
Co-authored-by: privacyguard <92675882+privacyguard@users.noreply.github.com>
Co-authored-by: privacyguard <privacyguard@users.noreply.github.com>
Co-authored-by: Freakazoid182 <5238563+Freakazoid182@users.noreply.github.com>
Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: leoseg <70430884+leoseg@users.noreply.github.com>
Co-authored-by: Sander Saarend <sander@saarend.com>
Co-authored-by: Joseph Silva <dull.bananas0@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: netbrum <130702882+netbrum@users.noreply.github.com>
Co-authored-by: Steven Vergenz <1882376+stevenvergenz@users.noreply.github.com>
Co-authored-by: Richard Schwab <gitrichardschwab-7a2qxq42kj@central-intelligence.agency>

* Search with LemmyErrorType prefix

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Carlos Cabello <carloscabello364@gmail.com>
Co-authored-by: privacyguard <92675882+privacyguard@users.noreply.github.com>
Co-authored-by: privacyguard <privacyguard@users.noreply.github.com>
Co-authored-by: Freakazoid182 <5238563+Freakazoid182@users.noreply.github.com>
Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: leoseg <70430884+leoseg@users.noreply.github.com>
Co-authored-by: Sander Saarend <sander@saarend.com>
Co-authored-by: Joseph Silva <dull.bananas0@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: netbrum <130702882+netbrum@users.noreply.github.com>
Co-authored-by: Steven Vergenz <1882376+stevenvergenz@users.noreply.github.com>
Co-authored-by: Richard Schwab <gitrichardschwab-7a2qxq42kj@central-intelligence.agency>
Co-authored-by: Dessalines <tyhou13@gmx.com>
This commit is contained in:
Nutomic 2024-10-28 16:07:13 +01:00 committed by GitHub
parent f05afead02
commit aef4403412
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 145 additions and 84 deletions

View file

@ -39,10 +39,7 @@ use lemmy_db_schema::{
}, },
traits::{Bannable, Crud, Followable}, traits::{Bannable, Crud, Followable},
}; };
use lemmy_utils::{ use lemmy_utils::error::{FederationError, LemmyError, LemmyResult};
error::{LemmyError, LemmyResult},
LemmyErrorType,
};
use url::Url; use url::Url;
impl BlockUser { impl BlockUser {
@ -135,7 +132,7 @@ impl ActivityHandler for BlockUser {
.object .object
.inner() .inner()
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)?; .ok_or(FederationError::UrlWithoutDomain)?;
if context.settings().hostname == domain { if context.settings().hostname == domain {
return Err( return Err(
anyhow!("Site bans from remote instance can't affect user's home instance").into(), anyhow!("Site bans from remote instance can't affect user's home instance").into(),

View file

@ -26,7 +26,7 @@ use lemmy_db_schema::{
source::{activity::ActivitySendTargets, community::CommunityFollower}, source::{activity::ActivitySendTargets, community::CommunityFollower},
CommunityVisibility, CommunityVisibility,
}; };
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
use serde_json::Value; use serde_json::Value;
use url::Url; use url::Url;
@ -54,7 +54,7 @@ impl ActivityHandler for RawAnnouncableActivities {
// This is only for sending, not receiving so we reject it. // This is only for sending, not receiving so we reject it.
if let AnnouncableActivities::Page(_) = activity { if let AnnouncableActivities::Page(_) = activity {
Err(LemmyErrorType::CannotReceivePage)? Err(FederationError::CannotReceivePage)?
} }
// Need to treat community as optional here because `Delete/PrivateMessage` gets routed through // Need to treat community as optional here because `Delete/PrivateMessage` gets routed through
@ -165,7 +165,7 @@ impl ActivityHandler for AnnounceActivity {
// This is only for sending, not receiving so we reject it. // This is only for sending, not receiving so we reject it.
if let AnnouncableActivities::Page(_) = object { if let AnnouncableActivities::Page(_) = object {
Err(LemmyErrorType::CannotReceivePage)? Err(FederationError::CannotReceivePage)?
} }
let community = object.community(context).await?; let community = object.community(context).await?;

View file

@ -27,7 +27,7 @@ use lemmy_db_schema::{
}, },
traits::{Crud, Reportable}, traits::{Crud, Reportable},
}; };
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
use url::Url; use url::Url;
#[async_trait::async_trait] #[async_trait::async_trait]
@ -118,7 +118,7 @@ pub(in crate::activities) async fn receive_remove_action(
match DeletableObjects::read_from_db(object, context).await? { match DeletableObjects::read_from_db(object, context).await? {
DeletableObjects::Community(community) => { DeletableObjects::Community(community) => {
if community.local { if community.local {
Err(LemmyErrorType::OnlyLocalAdminCanRemoveCommunity)? Err(FederationError::OnlyLocalAdminCanRemoveCommunity)?
} }
let form = ModRemoveCommunityForm { let form = ModRemoveCommunityForm {
mod_person_id: actor.id, mod_person_id: actor.id,

View file

@ -25,7 +25,7 @@ use lemmy_db_schema::{
}, },
traits::Crud, traits::Crud,
}; };
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
use url::Url; use url::Url;
#[async_trait::async_trait] #[async_trait::async_trait]
@ -100,7 +100,7 @@ impl UndoDelete {
match DeletableObjects::read_from_db(object, context).await? { match DeletableObjects::read_from_db(object, context).await? {
DeletableObjects::Community(community) => { DeletableObjects::Community(community) => {
if community.local { if community.local {
Err(LemmyErrorType::OnlyLocalAdminCanRestoreCommunity)? Err(FederationError::OnlyLocalAdminCanRestoreCommunity)?
} }
let form = ModRemoveCommunityForm { let form = ModRemoveCommunityForm {
mod_person_id: actor.id, mod_person_id: actor.id,

View file

@ -42,7 +42,7 @@ use lemmy_db_schema::{
traits::Crud, traits::Crud,
}; };
use lemmy_db_views_actor::structs::{CommunityPersonBanView, CommunityView}; use lemmy_db_views_actor::structs::{CommunityPersonBanView, CommunityView};
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult};
use serde::Serialize; use serde::Serialize;
use tracing::info; use tracing::info;
use url::{ParseError, Url}; use url::{ParseError, Url};
@ -81,7 +81,7 @@ pub(crate) async fn verify_person_in_community(
) -> LemmyResult<()> { ) -> LemmyResult<()> {
let person = person_id.dereference(context).await?; let person = person_id.dereference(context).await?;
if person.banned { if person.banned {
Err(LemmyErrorType::PersonIsBannedFromSite( Err(FederationError::PersonIsBannedFromSite(
person.actor_id.to_string(), person.actor_id.to_string(),
))? ))?
} }
@ -114,7 +114,7 @@ pub(crate) async fn verify_mod_action(
pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> { pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> {
if ![to, cc].iter().any(|set| set.contains(&public())) { if ![to, cc].iter().any(|set| set.contains(&public())) {
Err(LemmyErrorType::ObjectIsNotPublic)? Err(FederationError::ObjectIsNotPublic)?
} else { } else {
Ok(()) Ok(())
} }
@ -126,7 +126,7 @@ where
{ {
let b: ObjectId<ApubCommunity> = b.into(); let b: ObjectId<ApubCommunity> = b.into();
if a != &b { if a != &b {
Err(LemmyErrorType::InvalidCommunity)? Err(FederationError::InvalidCommunity)?
} else { } else {
Ok(()) Ok(())
} }
@ -134,7 +134,7 @@ where
pub(crate) fn check_community_deleted_or_removed(community: &Community) -> LemmyResult<()> { pub(crate) fn check_community_deleted_or_removed(community: &Community) -> LemmyResult<()> {
if community.deleted || community.removed { if community.deleted || community.removed {
Err(LemmyErrorType::CannotCreatePostOrCommentInDeletedOrRemovedCommunity)? Err(FederationError::CannotCreatePostOrCommentInDeletedOrRemovedCommunity)?
} else { } else {
Ok(()) Ok(())
} }

View file

@ -26,7 +26,7 @@ pub enum PostOrComment {
#[serde(untagged)] #[serde(untagged)]
pub enum PageOrNote { pub enum PageOrNote {
Page(Box<Page>), Page(Box<Page>),
Note(Note), Note(Box<Note>),
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@ -61,7 +61,7 @@ impl Object for PostOrComment {
async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> { async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
Ok(match self { Ok(match self {
PostOrComment::Post(p) => PageOrNote::Page(Box::new(p.into_json(data).await?)), PostOrComment::Post(p) => PageOrNote::Page(Box::new(p.into_json(data).await?)),
PostOrComment::Comment(c) => PageOrNote::Note(c.into_json(data).await?), PostOrComment::Comment(c) => PageOrNote::Note(Box::new(c.into_json(data).await?)),
}) })
} }
@ -81,7 +81,7 @@ impl Object for PostOrComment {
async fn from_json(apub: PageOrNote, context: &Data<LemmyContext>) -> LemmyResult<Self> { async fn from_json(apub: PageOrNote, context: &Data<LemmyContext>) -> LemmyResult<Self> {
Ok(match apub { Ok(match apub {
PageOrNote::Page(p) => PostOrComment::Post(ApubPost::from_json(*p, context).await?), PageOrNote::Page(p) => PostOrComment::Post(ApubPost::from_json(*p, context).await?),
PageOrNote::Note(n) => PostOrComment::Comment(ApubComment::from_json(n, context).await?), PageOrNote::Note(n) => PostOrComment::Comment(ApubComment::from_json(*n, context).await?),
}) })
} }
} }

View file

@ -17,7 +17,7 @@ use lemmy_db_schema::{
source::{activity::SentActivity, community::Community}, source::{activity::SentActivity, community::Community},
CommunityVisibility, CommunityVisibility,
}; };
use lemmy_utils::error::{LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyErrorType, LemmyResult};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ops::Deref, time::Duration}; use std::{ops::Deref, time::Duration};
use tokio::time::timeout; use tokio::time::timeout;
@ -45,7 +45,7 @@ pub async fn shared_inbox(
// consider the activity broken and move on. // consider the activity broken and move on.
timeout(INCOMING_ACTIVITY_TIMEOUT, receive_fut) timeout(INCOMING_ACTIVITY_TIMEOUT, receive_fut)
.await .await
.map_err(|_| LemmyErrorType::InboxTimeout)? .map_err(|_| FederationError::InboxTimeout)?
} }
/// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub /// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub
@ -106,7 +106,9 @@ pub(crate) async fn get_activity(
info.id info.id
))? ))?
.into(); .into();
let activity = SentActivity::read_from_apub_id(&mut context.pool(), &activity_id).await?; let activity = SentActivity::read_from_apub_id(&mut context.pool(), &activity_id)
.await
.map_err(|_| FederationError::CouldntFindActivity)?;
let sensitive = activity.sensitive; let sensitive = activity.sensitive;
if sensitive { if sensitive {

View file

@ -10,7 +10,7 @@ use lemmy_db_schema::{
utils::{ActualDbPool, DbPool}, utils::{ActualDbPool, DbPool},
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyErrorType, LemmyResult}, error::{FederationError, LemmyError, LemmyErrorType, LemmyResult},
CACHE_DURATION_FEDERATION, CACHE_DURATION_FEDERATION,
}; };
use moka::future::Cache; use moka::future::Cache;
@ -51,17 +51,18 @@ impl UrlVerifier for VerifyUrlData {
let local_site_data = local_site_data_cached(&mut (&self.0).into()) let local_site_data = local_site_data_cached(&mut (&self.0).into())
.await .await
.expect("read local site data"); .expect("read local site data");
use FederationError::*;
check_apub_id_valid(url, &local_site_data).map_err(|err| match err { check_apub_id_valid(url, &local_site_data).map_err(|err| match err {
LemmyError { LemmyError {
error_type: LemmyErrorType::FederationDisabled, error_type: LemmyErrorType::FederationError(Some(FederationDisabled)),
.. ..
} => ActivityPubError::Other("Federation disabled".into()), } => ActivityPubError::Other("Federation disabled".into()),
LemmyError { LemmyError {
error_type: LemmyErrorType::DomainBlocked(domain), error_type: LemmyErrorType::FederationError(Some(DomainBlocked(domain))),
.. ..
} => ActivityPubError::Other(format!("Domain {domain:?} is blocked")), } => ActivityPubError::Other(format!("Domain {domain:?} is blocked")),
LemmyError { LemmyError {
error_type: LemmyErrorType::DomainNotInAllowList(domain), error_type: LemmyErrorType::FederationError(Some(DomainNotInAllowList(domain))),
.. ..
} => ActivityPubError::Other(format!("Domain {domain:?} is not in allowlist")), } => ActivityPubError::Other(format!("Domain {domain:?} is not in allowlist")),
_ => ActivityPubError::Other("Failed validating apub id".into()), _ => ActivityPubError::Other("Failed validating apub id".into()),
@ -81,7 +82,7 @@ impl UrlVerifier for VerifyUrlData {
fn check_apub_id_valid(apub_id: &Url, local_site_data: &LocalSiteData) -> LemmyResult<()> { fn check_apub_id_valid(apub_id: &Url, local_site_data: &LocalSiteData) -> LemmyResult<()> {
let domain = apub_id let domain = apub_id
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)? .ok_or(FederationError::UrlWithoutDomain)?
.to_string(); .to_string();
if !local_site_data if !local_site_data
@ -90,7 +91,7 @@ fn check_apub_id_valid(apub_id: &Url, local_site_data: &LocalSiteData) -> LemmyR
.map(|l| l.federation_enabled) .map(|l| l.federation_enabled)
.unwrap_or(true) .unwrap_or(true)
{ {
Err(LemmyErrorType::FederationDisabled)? Err(FederationError::FederationDisabled)?
} }
if local_site_data if local_site_data
@ -98,7 +99,7 @@ fn check_apub_id_valid(apub_id: &Url, local_site_data: &LocalSiteData) -> LemmyR
.iter() .iter()
.any(|i| domain.to_lowercase().eq(&i.domain.to_lowercase())) .any(|i| domain.to_lowercase().eq(&i.domain.to_lowercase()))
{ {
Err(LemmyErrorType::DomainBlocked(domain.clone()))? Err(FederationError::DomainBlocked(domain.clone()))?
} }
// Only check this if there are instances in the allowlist // Only check this if there are instances in the allowlist
@ -108,7 +109,7 @@ fn check_apub_id_valid(apub_id: &Url, local_site_data: &LocalSiteData) -> LemmyR
.iter() .iter()
.any(|i| domain.to_lowercase().eq(&i.domain.to_lowercase())) .any(|i| domain.to_lowercase().eq(&i.domain.to_lowercase()))
{ {
Err(LemmyErrorType::DomainNotInAllowList(domain))? Err(FederationError::DomainNotInAllowList(domain))?
} }
Ok(()) Ok(())
@ -164,7 +165,7 @@ pub(crate) async fn check_apub_id_valid_with_strictness(
) -> LemmyResult<()> { ) -> LemmyResult<()> {
let domain = apub_id let domain = apub_id
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)? .ok_or(FederationError::UrlWithoutDomain)?
.to_string(); .to_string();
let local_instance = context let local_instance = context
.settings() .settings()
@ -194,10 +195,10 @@ pub(crate) async fn check_apub_id_valid_with_strictness(
let domain = apub_id let domain = apub_id
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)? .ok_or(FederationError::UrlWithoutDomain)?
.to_string(); .to_string();
if !allowed_and_local.contains(&domain) { if !allowed_and_local.contains(&domain) {
Err(LemmyErrorType::FederationDisabledByStrictAllowList)? Err(FederationError::FederationDisabledByStrictAllowList)?
} }
} }
Ok(()) Ok(())

View file

@ -11,7 +11,10 @@ use lemmy_db_schema::{
traits::Crud, traits::Crud,
utils::DbPool, utils::DbPool,
}; };
use lemmy_utils::{error::LemmyResult, utils::mention::scrape_text_for_mentions, LemmyErrorType}; use lemmy_utils::{
error::{FederationError, LemmyResult},
utils::mention::scrape_text_for_mentions,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use url::Url; use url::Url;
@ -57,7 +60,7 @@ pub async fn collect_non_local_mentions(
&parent_creator &parent_creator
.id() .id()
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)? .ok_or(FederationError::UrlWithoutDomain)?
)), )),
kind: MentionType::Mention, kind: MentionType::Mention,
}; };

View file

@ -33,7 +33,7 @@ use lemmy_db_schema::{
utils::naive_now, utils::naive_now,
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyErrorType, LemmyResult}, error::{FederationError, LemmyError, LemmyResult},
utils::markdown::markdown_to_html, utils::markdown::markdown_to_html,
}; };
use std::ops::Deref; use std::ops::Deref;
@ -162,7 +162,7 @@ impl Object for ApubComment {
.await .await
.is_ok(); .is_ok();
if post.locked && !is_mod_or_admin { if post.locked && !is_mod_or_admin {
Err(LemmyErrorType::PostIsLocked)? Err(FederationError::PostIsLocked)?
} else { } else {
Ok(()) Ok(())
} }

View file

@ -42,12 +42,11 @@ use lemmy_db_schema::{
utils::naive_now, utils::naive_now,
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyResult}, error::{FederationError, LemmyError, LemmyResult},
utils::{ utils::{
markdown::markdown_to_html, markdown::markdown_to_html,
slurs::{check_slurs, check_slurs_opt}, slurs::{check_slurs, check_slurs_opt},
}, },
LemmyErrorType,
}; };
use std::ops::Deref; use std::ops::Deref;
use tracing::debug; use tracing::debug;
@ -89,7 +88,7 @@ impl Object for ApubSite {
} }
async fn delete(self, _data: &Data<Self::DataType>) -> LemmyResult<()> { async fn delete(self, _data: &Data<Self::DataType>) -> LemmyResult<()> {
Err(LemmyErrorType::CantDeleteSite.into()) Err(FederationError::CantDeleteSite.into())
} }
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
@ -144,7 +143,7 @@ impl Object for ApubSite {
.id .id
.inner() .inner()
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)?; .ok_or(FederationError::UrlWithoutDomain)?;
let instance = DbInstance::read_or_create(&mut context.pool(), domain.to_string()).await?; let instance = DbInstance::read_or_create(&mut context.pool(), domain.to_string()).await?;
let local_site = LocalSite::read(&mut context.pool()).await.ok(); let local_site = LocalSite::read(&mut context.pool()).await.ok();
@ -220,7 +219,7 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object<T: Into<Url> + C
debug!("Failed to dereference site for {}: {}", &instance_id, e); debug!("Failed to dereference site for {}: {}", &instance_id, e);
let domain = instance_id let domain = instance_id
.domain() .domain()
.ok_or(LemmyErrorType::UrlWithoutDomain)?; .ok_or(FederationError::UrlWithoutDomain)?;
Ok( Ok(
DbInstance::read_or_create(&mut context.pool(), domain.to_string()) DbInstance::read_or_create(&mut context.pool(), domain.to_string())
.await? .await?

View file

@ -29,7 +29,7 @@ use lemmy_db_schema::{
utils::naive_now, utils::naive_now,
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyErrorType, LemmyResult}, error::{FederationError, LemmyError, LemmyErrorType, LemmyResult},
utils::markdown::markdown_to_html, utils::markdown::markdown_to_html,
}; };
use std::ops::Deref; use std::ops::Deref;
@ -113,7 +113,7 @@ impl Object for ApubPrivateMessage {
check_apub_id_valid_with_strictness(note.id.inner(), false, context).await?; check_apub_id_valid_with_strictness(note.id.inner(), false, context).await?;
let person = note.attributed_to.dereference(context).await?; let person = note.attributed_to.dereference(context).await?;
if person.banned { if person.banned {
Err(LemmyErrorType::PersonIsBannedFromSite( Err(FederationError::PersonIsBannedFromSite(
person.actor_id.to_string(), person.actor_id.to_string(),
))? ))?
} else { } else {

View file

@ -6,7 +6,7 @@ use crate::{
}; };
use activitypub_federation::{config::Data, fetch::object_id::ObjectId}; use activitypub_federation::{config::Data, fetch::object_id::ObjectId};
use lemmy_api_common::context::LemmyContext; use lemmy_api_common::context::LemmyContext;
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyResult};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::Display; use strum::Display;
use url::Url; use url::Url;
@ -35,7 +35,7 @@ impl TryFrom<i16> for VoteType {
match value { match value {
1 => Ok(VoteType::Like), 1 => Ok(VoteType::Like),
-1 => Ok(VoteType::Dislike), -1 => Ok(VoteType::Dislike),
_ => Err(LemmyErrorType::InvalidVoteValue.into()), _ => Err(FederationError::InvalidVoteValue.into()),
} }
} }
} }

View file

@ -20,7 +20,7 @@ use activitypub_federation::{
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use itertools::Itertools; use itertools::Itertools;
use lemmy_api_common::context::LemmyContext; use lemmy_api_common::context::LemmyContext;
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
use serde::{de::Error, Deserialize, Deserializer, Serialize}; use serde::{de::Error, Deserialize, Deserializer, Serialize};
use serde_with::skip_serializing_none; use serde_with::skip_serializing_none;
use url::Url; use url::Url;
@ -162,7 +162,7 @@ impl Page {
.iter() .iter()
.find(|a| a.kind == PersonOrGroupType::Person) .find(|a| a.kind == PersonOrGroupType::Person)
.map(|a| ObjectId::<ApubPerson>::from(a.id.clone().into_inner())) .map(|a| ObjectId::<ApubPerson>::from(a.id.clone().into_inner()))
.ok_or_else(|| LemmyErrorType::PageDoesNotSpecifyCreator.into()), .ok_or_else(|| FederationError::PageDoesNotSpecifyCreator.into()),
} }
} }
} }

View file

@ -23,30 +23,24 @@ pub enum LemmyErrorType {
CouldntUpdateComment, CouldntUpdateComment,
CouldntUpdatePrivateMessage, CouldntUpdatePrivateMessage,
CannotLeaveAdmin, CannotLeaveAdmin,
NoLinesInHtml, // TODO: also remove the translations of unused errors
SiteMetadataPageIsNotDoctypeHtml,
PictrsResponseError(String), PictrsResponseError(String),
PictrsPurgeResponseError(String), PictrsPurgeResponseError(String),
PictrsCachingDisabled,
ImageUrlMissingPathSegments, ImageUrlMissingPathSegments,
ImageUrlMissingLastPathSegment, ImageUrlMissingLastPathSegment,
PictrsApiKeyNotProvided, PictrsApiKeyNotProvided,
NoContentTypeHeader, NoContentTypeHeader,
NotAnImageType, NotAnImageType,
NotAModOrAdmin, NotAModOrAdmin,
NoAdmins,
NotTopAdmin,
NotTopMod, NotTopMod,
NotLoggedIn, NotLoggedIn,
NotHigherMod, NotHigherMod,
NotHigherAdmin, NotHigherAdmin,
SiteBan, SiteBan,
Deleted, Deleted,
BannedFromCommunity,
PersonIsBlocked, PersonIsBlocked,
CommunityIsBlocked, CommunityIsBlocked,
InstanceIsBlocked, InstanceIsBlocked,
VoteNotAllowed,
InstanceIsPrivate, InstanceIsPrivate,
/// Password must be between 10 and 60 characters /// Password must be between 10 and 60 characters
InvalidPassword, InvalidPassword,
@ -61,7 +55,6 @@ pub enum LemmyErrorType {
OnlyAdminsCanCreateCommunities, OnlyAdminsCanCreateCommunities,
CommunityAlreadyExists, CommunityAlreadyExists,
LanguageNotAllowed, LanguageNotAllowed,
OnlyModsCanPostInCommunity,
CouldntUpdatePost, CouldntUpdatePost,
NoPostEditAllowed, NoPostEditAllowed,
EditPrivateMessageNotAllowed, EditPrivateMessageNotAllowed,
@ -73,23 +66,10 @@ pub enum LemmyErrorType {
RegistrationUsernameRequired, RegistrationUsernameRequired,
EmailAlreadyExists, EmailAlreadyExists,
UsernameAlreadyExists, UsernameAlreadyExists,
FederationForbiddenByStrictAllowList,
PersonIsBannedFromCommunity, PersonIsBannedFromCommunity,
ObjectIsNotPublic,
InvalidCommunity,
CannotCreatePostOrCommentInDeletedOrRemovedCommunity,
CannotReceivePage,
NewPostCannotBeLocked,
OnlyLocalAdminCanRemoveCommunity,
OnlyLocalAdminCanRestoreCommunity,
NoIdGiven, NoIdGiven,
IncorrectLogin, IncorrectLogin,
InvalidQuery,
ObjectNotLocal, ObjectNotLocal,
PostIsLocked,
PersonIsBannedFromSite(String),
InvalidVoteValue,
PageDoesNotSpecifyCreator,
NoEmailSetup, NoEmailSetup,
LocalSiteNotSetup, LocalSiteNotSetup,
EmailSmtpServerNeedsAPort, EmailSmtpServerNeedsAPort,
@ -126,7 +106,6 @@ pub enum LemmyErrorType {
CouldntUpdateCommunity, CouldntUpdateCommunity,
CouldntUpdateReplies, CouldntUpdateReplies,
CouldntUpdatePersonMentions, CouldntUpdatePersonMentions,
PostTitleTooLong,
CouldntCreatePost, CouldntCreatePost,
CouldntCreatePrivateMessage, CouldntCreatePrivateMessage,
CouldntUpdatePrivate, CouldntUpdatePrivate,
@ -141,10 +120,6 @@ pub enum LemmyErrorType {
EmailSendFailed, EmailSendFailed,
Slurs, Slurs,
RegistrationDenied(Option<String>), RegistrationDenied(Option<String>),
FederationDisabled,
DomainBlocked(String),
DomainNotInAllowList(String),
FederationDisabledByStrictAllowList,
SiteNameRequired, SiteNameRequired,
SiteNameLengthOverflow, SiteNameLengthOverflow,
PermissiveRegex, PermissiveRegex,
@ -158,23 +133,51 @@ pub enum LemmyErrorType {
/// Thrown when an API call is submitted with more than 1000 array elements, see /// Thrown when an API call is submitted with more than 1000 array elements, see
/// [[MAX_API_PARAM_ELEMENTS]] /// [[MAX_API_PARAM_ELEMENTS]]
TooManyItems, TooManyItems,
CommunityHasNoFollowers,
BanExpirationInPast, BanExpirationInPast,
InvalidUnixTime, InvalidUnixTime,
InvalidBotAction, InvalidBotAction,
CantBlockLocalInstance, CantBlockLocalInstance,
UrlWithoutDomain, Unknown(String),
InboxTimeout, UrlLengthOverflow,
OauthAuthorizationInvalid, OauthAuthorizationInvalid,
OauthLoginFailed, OauthLoginFailed,
OauthRegistrationClosed, OauthRegistrationClosed,
CouldntDeleteOauthProvider, CouldntDeleteOauthProvider,
Unknown(String), NotFound,
CantDeleteSite, CommunityHasNoFollowers,
UrlLengthOverflow,
PostScheduleTimeMustBeInFuture, PostScheduleTimeMustBeInFuture,
TooManyScheduledPosts, TooManyScheduledPosts,
NotFound, FederationError(Option<FederationError>),
}
/// Federation related errors, these dont need to be translated.
#[derive(Display, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, EnumIter, Hash)]
#[cfg_attr(feature = "full", derive(ts_rs::TS))]
#[cfg_attr(feature = "full", ts(export))]
#[non_exhaustive]
pub enum FederationError {
// TODO: merge into a single NotFound error
CouldntFindActivity,
InvalidCommunity,
CannotCreatePostOrCommentInDeletedOrRemovedCommunity,
CannotReceivePage,
OnlyLocalAdminCanRemoveCommunity,
OnlyLocalAdminCanRestoreCommunity,
PostIsLocked,
PersonIsBannedFromSite(String),
InvalidVoteValue,
PageDoesNotSpecifyCreator,
CouldntGetComments,
CouldntGetPosts,
FederationDisabled,
DomainBlocked(String),
DomainNotInAllowList(String),
FederationDisabledByStrictAllowList,
ContradictingFilters,
UrlWithoutDomain,
InboxTimeout,
CantDeleteSite,
ObjectIsNotPublic,
} }
cfg_if! { cfg_if! {
@ -255,6 +258,17 @@ cfg_if! {
} }
} }
impl From<FederationError> for LemmyError {
fn from(error_type: FederationError) -> Self {
let inner = anyhow::anyhow!("{}", error_type);
LemmyError {
error_type: LemmyErrorType::FederationError(Some(error_type)),
inner,
context: Backtrace::capture(),
}
}
}
pub trait LemmyErrorExt<T, E: Into<anyhow::Error>> { pub trait LemmyErrorExt<T, E: Into<anyhow::Error>> {
fn with_lemmy_type(self, error_type: LemmyErrorType) -> LemmyResult<T>; fn with_lemmy_type(self, error_type: LemmyErrorType) -> LemmyResult<T>;
} }
@ -306,12 +320,12 @@ cfg_if! {
#[test] #[test]
fn deserializes_with_message() -> LemmyResult<()> { fn deserializes_with_message() -> LemmyResult<()> {
let reg_banned = LemmyErrorType::PersonIsBannedFromSite(String::from("reason")); let reg_banned = LemmyErrorType::PictrsResponseError(String::from("reason"));
let err = LemmyError::from(reg_banned).error_response(); let err = LemmyError::from(reg_banned).error_response();
let json = String::from_utf8(err.into_body().try_into_bytes().unwrap_or_default().to_vec())?; let json = String::from_utf8(err.into_body().try_into_bytes().unwrap_or_default().to_vec())?;
assert_eq!( assert_eq!(
&json, &json,
"{\"error\":\"person_is_banned_from_site\",\"message\":\"reason\"}" "{\"error\":\"pictrs_response_error\",\"message\":\"reason\"}"
); );
Ok(()) Ok(())

View file

@ -0,0 +1,45 @@
use lemmy_utils::LemmyErrorType;
use std::{env::current_dir, process::Command};
use strum::IntoEnumIterator;
#[test]
#[allow(clippy::unwrap_used)]
fn test_errors_used() {
let mut unused_error_found = false;
let mut current_dir = current_dir().unwrap();
current_dir.pop();
current_dir.pop();
for error in LemmyErrorType::iter() {
let search = format!("LemmyErrorType::{error}");
let mut grep_all = Command::new("grep");
let grep_all = grep_all
.current_dir(current_dir.clone())
.arg("-R")
.arg("--exclude=error.rs")
.arg(&search)
.arg("crates/")
.arg("src/");
let output = grep_all.output().unwrap();
let grep_all_out = std::str::from_utf8(&output.stdout).unwrap();
let mut grep_apub = Command::new("grep");
let grep_apub = grep_apub
.current_dir(current_dir.clone())
.arg("-R")
.arg("--exclude-dir=api")
.arg(&search)
.arg("crates/apub/");
let output = grep_apub.output().unwrap();
let grep_apub_out = std::str::from_utf8(&output.stdout).unwrap();
if grep_all_out.is_empty() {
println!("LemmyErrorType::{} is unused", error);
unused_error_found = true;
}
if search != "LemmyErrorType::FederationError" && grep_all_out == grep_apub_out {
println!("LemmyErrorType::{} is only used for federation", error);
unused_error_found = true;
}
}
assert!(!unused_error_found);
}