2024-05-28 15:29:18 +02:00
|
|
|
using System.Net;
|
|
|
|
using Foxnouns.Backend.Middleware;
|
|
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
|
|
namespace Foxnouns.Backend;
|
|
|
|
|
|
|
|
public class FoxnounsError(string message, Exception? inner = null) : Exception(message)
|
|
|
|
{
|
|
|
|
public Exception? Inner => inner;
|
|
|
|
|
|
|
|
public class DatabaseError(string message, Exception? inner = null) : FoxnounsError(message, inner);
|
|
|
|
|
|
|
|
public class UnknownEntityError(Type entityType, Exception? inner = null)
|
|
|
|
: DatabaseError($"Entity of type {entityType.Name} not found", inner);
|
|
|
|
}
|
|
|
|
|
2024-05-28 17:09:50 +02:00
|
|
|
public class ApiError(string message, HttpStatusCode? statusCode = null, ErrorCode? errorCode = null)
|
|
|
|
: FoxnounsError(message)
|
2024-05-28 15:29:18 +02:00
|
|
|
{
|
|
|
|
public readonly HttpStatusCode StatusCode = statusCode ?? HttpStatusCode.InternalServerError;
|
2024-05-28 17:09:50 +02:00
|
|
|
public readonly ErrorCode ErrorCode = errorCode ?? ErrorCode.InternalServerError;
|
2024-05-28 15:29:18 +02:00
|
|
|
|
|
|
|
public class Unauthorized(string message) : ApiError(message, statusCode: HttpStatusCode.Unauthorized);
|
|
|
|
|
|
|
|
public class Forbidden(string message, IEnumerable<string>? scopes = null)
|
|
|
|
: ApiError(message, statusCode: HttpStatusCode.Forbidden)
|
|
|
|
{
|
|
|
|
public readonly string[] Scopes = scopes?.ToArray() ?? [];
|
|
|
|
}
|
|
|
|
|
|
|
|
public class BadRequest(string message, ModelStateDictionary? modelState = null)
|
|
|
|
: ApiError(message, statusCode: HttpStatusCode.BadRequest)
|
|
|
|
{
|
|
|
|
public JObject ToJson()
|
|
|
|
{
|
|
|
|
var o = new JObject
|
|
|
|
{
|
|
|
|
{ "status", (int)HttpStatusCode.BadRequest },
|
|
|
|
{ "code", ErrorCode.BadRequest.ToString() }
|
|
|
|
};
|
2024-05-28 17:09:50 +02:00
|
|
|
if (modelState == null) return o;
|
2024-05-28 15:29:18 +02:00
|
|
|
|
|
|
|
var a = new JArray();
|
2024-05-28 17:09:50 +02:00
|
|
|
foreach (var error in modelState.Where(e => e.Value is { Errors.Count: > 0 }))
|
2024-05-28 15:29:18 +02:00
|
|
|
{
|
|
|
|
var errorObj = new JObject
|
|
|
|
{
|
|
|
|
{ "key", error.Key },
|
|
|
|
{
|
|
|
|
"errors",
|
|
|
|
new JArray(error.Value!.Errors.Select(e => new JObject { { "message", e.ErrorMessage } }))
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
a.Add(errorObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
o.Add("errors", a);
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-28 17:09:50 +02:00
|
|
|
public class NotFound(string message, ErrorCode? code = null)
|
|
|
|
: ApiError(message, statusCode: HttpStatusCode.NotFound, errorCode: code);
|
2024-05-28 15:29:18 +02:00
|
|
|
|
|
|
|
public class AuthenticationError(string message) : ApiError(message, statusCode: HttpStatusCode.BadRequest);
|
2024-05-28 17:09:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public enum ErrorCode
|
|
|
|
{
|
|
|
|
InternalServerError,
|
|
|
|
Forbidden,
|
|
|
|
BadRequest,
|
|
|
|
AuthenticationError,
|
|
|
|
GenericApiError,
|
|
|
|
UserNotFound,
|
2024-05-30 16:59:40 +02:00
|
|
|
MemberNotFound,
|
2024-05-28 15:29:18 +02:00
|
|
|
}
|