[backend] Rework GracefulException throws without additional detail
This commit is contained in:
parent
d1721d71c2
commit
1c2079e1ee
11 changed files with 31 additions and 30 deletions
|
@ -3,7 +3,6 @@ using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
|
|||
using Iceshrimp.Backend.Core.Database;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Extensions;
|
||||
using Iceshrimp.Backend.Core.Middleware;
|
||||
using Iceshrimp.Backend.Core.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
|
@ -16,7 +15,7 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
|
|||
IEnumerable<StatusEntity>? statuses = null, Dictionary<string, string>? emojiUrls = null
|
||||
)
|
||||
{
|
||||
var dbNotifier = notification.Notifier ?? throw new GracefulException("Notification has no notifier");
|
||||
var dbNotifier = notification.Notifier ?? throw new Exception("Notification has no notifier");
|
||||
|
||||
var targetNote = notification.Note;
|
||||
|
||||
|
|
|
@ -109,9 +109,9 @@ public class AuthController(DatabaseContext db, UserService userSvc, UserRendere
|
|||
Justification = "Argon2 is execution time-heavy by design")]
|
||||
public async Task<AuthResponse> ChangePassword([FromBody] ChangePasswordRequest request)
|
||||
{
|
||||
var user = HttpContext.GetUser() ?? throw new GracefulException("HttpContext.GetUser() was null");
|
||||
var user = HttpContext.GetUserOrFail();
|
||||
var settings = await db.UserSettings.FirstOrDefaultAsync(p => p.User == user);
|
||||
if (settings is not { Password: not null }) throw new GracefulException("settings?.Password was null");
|
||||
if (settings is not { Password: not null }) throw new Exception("settings?.Password was null");
|
||||
if (!AuthHelpers.ComparePassword(request.OldPassword, settings.Password))
|
||||
throw GracefulException.BadRequest("old_password is invalid");
|
||||
if (request.NewPassword.Length < 8)
|
||||
|
|
|
@ -202,7 +202,7 @@ public static class QueryableExtensions
|
|||
.OfType<LinkPaginationAttribute>()
|
||||
.FirstOrDefault();
|
||||
if (filter == null)
|
||||
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
|
||||
throw new Exception("Route doesn't have a LinkPaginationAttribute");
|
||||
|
||||
return Paginate(query, pq, filter.DefaultLimit, filter.MaxLimit);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ public static class QueryableExtensions
|
|||
.OfType<LinkPaginationAttribute>()
|
||||
.FirstOrDefault();
|
||||
if (filter == null)
|
||||
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
|
||||
throw new Exception("Route doesn't have a LinkPaginationAttribute");
|
||||
|
||||
return PaginateByOffset(query, pq, filter.DefaultLimit, filter.MaxLimit);
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ public static class QueryableExtensions
|
|||
.OfType<LinkPaginationAttribute>()
|
||||
.FirstOrDefault();
|
||||
if (filter == null)
|
||||
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
|
||||
throw new Exception("Route doesn't have a LinkPaginationAttribute");
|
||||
|
||||
return Paginate(query, predicate, pq, filter.DefaultLimit, filter.MaxLimit);
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ public static class QueryableExtensions
|
|||
.OfType<LinkPaginationAttribute>()
|
||||
.FirstOrDefault();
|
||||
if (filter == null)
|
||||
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
|
||||
throw new Exception("Route doesn't have a LinkPaginationAttribute");
|
||||
|
||||
return Paginate(query, predicate, pq, filter.DefaultLimit, filter.MaxLimit);
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ public static class QueryableExtensions
|
|||
.OfType<LinkPaginationAttribute>()
|
||||
.FirstOrDefault();
|
||||
if (filter == null)
|
||||
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
|
||||
throw new Exception("Route doesn't have a LinkPaginationAttribute");
|
||||
|
||||
return Paginate(query, pq, filter.DefaultLimit, filter.MaxLimit);
|
||||
}
|
||||
|
|
|
@ -145,12 +145,14 @@ public class ActivityFetcherService(
|
|||
var input = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<JObject?>(input);
|
||||
|
||||
var res = LdHelpers.Expand(json) ?? throw new GracefulException("Failed to expand JSON-LD object");
|
||||
var res = LdHelpers.Expand(json) ??
|
||||
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Failed to expand JSON-LD object");
|
||||
if (res.Count != 1)
|
||||
throw new GracefulException("Received zero or more than one activity");
|
||||
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Received zero or more than one activity");
|
||||
|
||||
var activity = res[0].ToObject<ASObject>(new JsonSerializer { Converters = { new ASObjectConverter() } }) ??
|
||||
throw new GracefulException("Failed to deserialize activity");
|
||||
throw new GracefulException(HttpStatusCode.UnprocessableEntity,
|
||||
"Failed to deserialize activity");
|
||||
|
||||
if (finalUri.Host == config.Value.WebDomain || finalUri.Host == config.Value.WebDomain)
|
||||
throw GracefulException.UnprocessableEntity("Refusing to process activity from local domain");
|
||||
|
@ -214,7 +216,7 @@ public class ActivityFetcherService(
|
|||
{
|
||||
var activity = await FetchActivityAsync(uri, actor, keypair);
|
||||
return activity.OfType<ASActor>().FirstOrDefault() ??
|
||||
throw new GracefulException($"Failed to fetch actor: {uri}");
|
||||
throw new Exception($"Failed to fetch actor: {uri}");
|
||||
}
|
||||
|
||||
public async Task<ASActor> FetchActorAsync(string uri)
|
||||
|
|
|
@ -4,7 +4,6 @@ using Iceshrimp.Backend.Core.Database;
|
|||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
|
||||
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
|
||||
using Iceshrimp.Backend.Core.Middleware;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
@ -20,7 +19,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
|
|||
public ASActor RenderLite(User user)
|
||||
{
|
||||
return user.IsRemoteUser
|
||||
? new ASActor { Id = user.Uri ?? throw new GracefulException("Remote user must have an URI") }
|
||||
? new ASActor { Id = user.Uri ?? throw new Exception("Remote user must have an URI") }
|
||||
: new ASActor { Id = user.GetPublicUri(config.Value) };
|
||||
}
|
||||
|
||||
|
@ -28,13 +27,13 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
|
|||
{
|
||||
if (user.IsRemoteUser)
|
||||
{
|
||||
return new ASActor { Id = user.Uri ?? throw new GracefulException("Remote user must have an URI") };
|
||||
return new ASActor { Id = user.Uri ?? throw new Exception("Remote user must have an URI") };
|
||||
}
|
||||
|
||||
var profile = await db.UserProfiles.FirstOrDefaultAsync(p => p.User == user);
|
||||
var keypair = await db.UserKeypairs.FirstOrDefaultAsync(p => p.User == user);
|
||||
|
||||
if (keypair == null) throw new GracefulException("User has no keypair");
|
||||
if (keypair == null) throw new Exception("User has no keypair");
|
||||
|
||||
var id = user.GetPublicUri(config.Value);
|
||||
var type = Constants.SystemUsers.Contains(user.UsernameLower)
|
||||
|
|
|
@ -151,7 +151,7 @@ public class UserResolver(
|
|||
|
||||
fingerRes = await webFingerSvc.ResolveAsync(acctUri);
|
||||
|
||||
if (fingerRes == null) throw new GracefulException($"Failed to WebFinger '{acctUri}'");
|
||||
if (fingerRes == null) throw new Exception($"Failed to WebFinger '{acctUri}'");
|
||||
responses.Add(acctUri, fingerRes);
|
||||
}
|
||||
|
||||
|
@ -159,14 +159,14 @@ public class UserResolver(
|
|||
throw new Exception($"WebFinger response for '{acctUri}' didn't contain any acct uris");
|
||||
var finalUri = fingerRes.Links.FirstOrDefault(p => p is { Rel: "self", Type: "application/activity+json" })
|
||||
?.Href ??
|
||||
throw new GracefulException("Final AP URI was null");
|
||||
throw new Exception("Final AP URI was null");
|
||||
|
||||
if (apUri != finalUri)
|
||||
{
|
||||
logger.LogDebug("WebFinger: finalUri doesn't match apUri, setting acct host to apUri host: {apUri}", apUri);
|
||||
var split = finalAcct.Split('@');
|
||||
if (split.Length != 2)
|
||||
throw new GracefulException($"Failed to finalize WebFinger for '{apUri}': invalid acct '{finalAcct}'");
|
||||
throw new Exception($"Failed to finalize WebFinger for '{apUri}': invalid acct '{finalAcct}'");
|
||||
split[1] = new Uri(apUri).Host;
|
||||
finalAcct = string.Join('@', split);
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ public static partial class HttpContextExtensions
|
|||
|
||||
public static User GetUserOrFail(this HttpContext ctx)
|
||||
{
|
||||
return ctx.GetUser() ?? throw new GracefulException("Failed to get user from HttpContext");
|
||||
return ctx.GetUser() ?? throw new Exception("Failed to get user from HttpContext");
|
||||
}
|
||||
|
||||
public static bool ShouldHideFooter(this HttpContext ctx)
|
||||
|
|
|
@ -76,16 +76,15 @@ public class AuthorizedFetchMiddleware(
|
|||
catch (Exception e)
|
||||
{
|
||||
if (e is GracefulException) throw;
|
||||
throw new
|
||||
GracefulException($"Failed to fetch key of signature user ({sig.KeyId}) - {e.Message}");
|
||||
throw new Exception($"Failed to fetch key of signature user ({sig.KeyId}) - {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// If we still don't have the key, something went wrong and we need to throw an exception
|
||||
if (key == null) throw new GracefulException($"Failed to fetch key of signature user ({sig.KeyId})");
|
||||
if (key == null) throw new Exception($"Failed to fetch key of signature user ({sig.KeyId})");
|
||||
|
||||
if (key.User.IsLocalUser)
|
||||
throw new GracefulException("Remote user must have a host");
|
||||
throw new Exception("Remote user must have a host");
|
||||
|
||||
// We want to check both the user host & the keyId host (as account & web domain might be different)
|
||||
if (await fedCtrlSvc.ShouldBlockAsync(key.User.Host, key.KeyId))
|
||||
|
|
|
@ -89,7 +89,8 @@ public class InboxValidationMiddleware(
|
|||
if (obj == null)
|
||||
throw new Exception("Failed to deserialize ASObject");
|
||||
if (obj is not ASActivity activity)
|
||||
throw new GracefulException("Request body is not an ASActivity", $"Type: {obj.Type}");
|
||||
throw new GracefulException(HttpStatusCode.UnprocessableEntity,
|
||||
"Request body is not an ASActivity", $"Type: {obj.Type}");
|
||||
|
||||
UserPublickey? key = null;
|
||||
var verified = false;
|
||||
|
@ -128,7 +129,7 @@ public class InboxValidationMiddleware(
|
|||
if (key == null) throw new GracefulException($"Failed to fetch key of signature user ({sig.KeyId})");
|
||||
|
||||
if (key.User.IsLocalUser)
|
||||
throw new GracefulException("Remote user must have a host");
|
||||
throw new Exception("Remote user must have a host");
|
||||
|
||||
// We want to check both the user host & the keyId host (as account & web domain might be different)
|
||||
if (await fedCtrlSvc.ShouldBlockAsync(key.User.Host, key.KeyId))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Net;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Federation.ActivityStreams;
|
||||
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
|
||||
|
@ -22,7 +23,8 @@ public class InboxQueue(int parallelism)
|
|||
var expanded = LdHelpers.Expand(JToken.Parse(jobData.Body)) ?? throw new Exception("Failed to expand ASObject");
|
||||
var obj = ASObject.Deserialize(expanded) ?? throw new Exception("Failed to deserialize ASObject");
|
||||
if (obj is not ASActivity activity)
|
||||
throw new GracefulException("Job data is not an ASActivity", $"Type: {obj.Type}");
|
||||
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Job data is not an ASActivity",
|
||||
$"Type: {obj.Type}");
|
||||
|
||||
var apHandler = scope.GetRequiredService<ActivityPub.ActivityHandlerService>();
|
||||
try
|
||||
|
|
|
@ -3,7 +3,6 @@ using AsyncKeyedLock;
|
|||
using Iceshrimp.Backend.Core.Database;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Helpers;
|
||||
using Iceshrimp.Backend.Core.Middleware;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Iceshrimp.Backend.Core.Services;
|
||||
|
@ -67,7 +66,7 @@ public class SystemUserService(ILogger<SystemUserService> logger, DatabaseContex
|
|||
private async Task<User> CreateSystemUserAsync(string username)
|
||||
{
|
||||
if (await db.Users.AnyAsync(p => p.UsernameLower == username.ToLowerInvariant() && p.IsLocalUser))
|
||||
throw new GracefulException($"System user {username} already exists");
|
||||
throw new Exception($"System user {username} already exists");
|
||||
|
||||
var keypair = RSA.Create(4096);
|
||||
var user = new User
|
||||
|
|
Loading…
Add table
Reference in a new issue