73 lines
2.4 KiB
C#
73 lines
2.4 KiB
C#
|
|
// Copyright (C) 2021-present sam (starshines.gay)
|
||
|
|
//
|
||
|
|
// This program is free software: you can redistribute it and/or modify
|
||
|
|
// it under the terms of the GNU Affero General Public License as published
|
||
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
||
|
|
// (at your option) any later version.
|
||
|
|
//
|
||
|
|
// This program is distributed in the hope that it will be useful,
|
||
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
// GNU Affero General Public License for more details.
|
||
|
|
//
|
||
|
|
// You should have received a copy of the GNU Affero General Public License
|
||
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
|
|
||
|
|
using System.Net;
|
||
|
|
using System.Text.Json.Serialization;
|
||
|
|
|
||
|
|
namespace Catalogger.Backend.Api.Middleware;
|
||
|
|
|
||
|
|
public class ErrorMiddleware(ILogger baseLogger) : IMiddleware
|
||
|
|
{
|
||
|
|
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await next(context);
|
||
|
|
}
|
||
|
|
catch (ApiError ae)
|
||
|
|
{
|
||
|
|
context.Response.StatusCode = (int)ae.StatusCode;
|
||
|
|
await context.Response.WriteAsJsonAsync(ae.ToJson());
|
||
|
|
}
|
||
|
|
catch (Exception e)
|
||
|
|
{
|
||
|
|
var type = e.TargetSite?.DeclaringType ?? typeof(ErrorMiddleware);
|
||
|
|
var typeName = e.TargetSite?.DeclaringType?.FullName ?? "<unknown>";
|
||
|
|
var logger = baseLogger.ForContext(type);
|
||
|
|
|
||
|
|
logger.Error(e, "Error in {ClassName} ({Path})", typeName, context.Request.Path);
|
||
|
|
|
||
|
|
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
|
||
|
|
await context.Response.WriteAsJsonAsync(
|
||
|
|
new ApiError(
|
||
|
|
HttpStatusCode.InternalServerError,
|
||
|
|
ErrorCode.InternalServerError,
|
||
|
|
"Internal server error"
|
||
|
|
).ToJson()
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ApiError(HttpStatusCode statusCode, ErrorCode errorCode, string message)
|
||
|
|
: Exception(message)
|
||
|
|
{
|
||
|
|
public HttpStatusCode StatusCode { get; init; } = statusCode;
|
||
|
|
public ErrorCode ErrorCode { get; init; } = errorCode;
|
||
|
|
|
||
|
|
private record Json(ErrorCode ErrorCode, string Message);
|
||
|
|
|
||
|
|
public object ToJson() => new Json(ErrorCode, Message);
|
||
|
|
}
|
||
|
|
|
||
|
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||
|
|
public enum ErrorCode
|
||
|
|
{
|
||
|
|
InternalServerError,
|
||
|
|
BadRequest,
|
||
|
|
AuthRequired,
|
||
|
|
UnknownGuild,
|
||
|
|
}
|