feat(apiv2): basic error handling
This commit is contained in:
parent
9bafc732ab
commit
9d47bfe0d8
51
PluralKit.API/Errors.cs
Normal file
51
PluralKit.API/Errors.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class PKError: Exception
|
||||
{
|
||||
public int ResponseCode { get; init; }
|
||||
public int JsonCode { get; init; }
|
||||
public PKError(int code, int json_code, string message) : base(message)
|
||||
{
|
||||
ResponseCode = code;
|
||||
JsonCode = json_code;
|
||||
}
|
||||
|
||||
public JObject ToJson()
|
||||
{
|
||||
var j = new JObject();
|
||||
j.Add("message", this.Message);
|
||||
j.Add("code", this.JsonCode);
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
public class ModelParseError: PKError
|
||||
{
|
||||
public ModelParseError() : base(400, 0, "Error parsing JSON model")
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
public new JObject ToJson()
|
||||
{
|
||||
var j = base.ToJson();
|
||||
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
public static class APIErrors
|
||||
{
|
||||
public static PKError GenericBadRequest = new(400, 0, "400: Bad Request");
|
||||
public static PKError SystemNotFound = new(404, 20001, "System not found.");
|
||||
public static PKError MemberNotFound = new(404, 20002, "Member not found.");
|
||||
public static PKError GroupNotFound = new(404, 20003, "Group not found.");
|
||||
public static PKError UnauthorizedMemberList = new(403, 30001, "Unauthorized to view member list");
|
||||
public static PKError UnauthorizedGroupList = new(403, 30002, "Unauthorized to view group list");
|
||||
public static PKError Unimplemented = new(501, 50001, "Unimplemented");
|
||||
}
|
||||
}
|
@ -7,7 +7,9 @@ using Autofac;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Versioning;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -15,6 +17,10 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using Serilog;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
||||
namespace PluralKit.API
|
||||
@ -91,7 +97,7 @@ namespace PluralKit.API
|
||||
builder.RegisterInstance(InitUtils.BuildConfiguration(Environment.GetCommandLineArgs()).Build())
|
||||
.As<IConfiguration>();
|
||||
builder.RegisterModule(new ConfigModule<ApiConfig>("API"));
|
||||
builder.RegisterModule(new LoggingModule("api"));
|
||||
builder.RegisterModule(new LoggingModule("api", cfg: new LoggerConfiguration().Filter.ByExcluding(exc => exc.Exception is PKError)));
|
||||
builder.RegisterModule(new MetricsModule("API"));
|
||||
builder.RegisterModule<DataStoreModule>();
|
||||
builder.RegisterModule<APIModule>();
|
||||
@ -124,6 +130,23 @@ namespace PluralKit.API
|
||||
return next();
|
||||
});
|
||||
|
||||
app.UseExceptionHandler(handler => handler.Run(async ctx =>
|
||||
{
|
||||
var exc = ctx.Features.Get<IExceptionHandlerPathFeature>();
|
||||
if (exc.Error is not PKError)
|
||||
{
|
||||
ctx.Response.StatusCode = 500;
|
||||
await ctx.Response.WriteAsync("{\"message\":\"500: Internal Server Error\",\"code\":0}");
|
||||
return;
|
||||
}
|
||||
|
||||
var err = (PKError)exc.Error;
|
||||
ctx.Response.StatusCode = err.ResponseCode;
|
||||
|
||||
var json = JsonConvert.SerializeObject(err.ToJson());
|
||||
await ctx.Response.WriteAsync(json);
|
||||
}));
|
||||
|
||||
app.UseMiddleware<AuthorizationTokenHandlerMiddleware>();
|
||||
|
||||
//app.UseHttpsRedirection();
|
||||
|
@ -17,11 +17,13 @@ namespace PluralKit.Core
|
||||
{
|
||||
private readonly string _component;
|
||||
private readonly Action<LoggerConfiguration> _fn;
|
||||
private LoggerConfiguration _cfg { get; init; }
|
||||
|
||||
public LoggingModule(string component, Action<LoggerConfiguration> fn = null)
|
||||
public LoggingModule(string component, Action<LoggerConfiguration> fn = null, LoggerConfiguration cfg = null)
|
||||
{
|
||||
_component = component;
|
||||
_fn = fn ?? (_ => { });
|
||||
_cfg = cfg ?? new LoggerConfiguration();
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
@ -44,7 +46,7 @@ namespace PluralKit.Core
|
||||
var consoleTemplate = "[{Timestamp:HH:mm:ss.fff}] {Level:u3} {Message:lj}{NewLine}{Exception}";
|
||||
var outputTemplate = "[{Timestamp:yyyy-MM-dd HH:mm:ss.ffffff}] {Level:u3} {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
var logCfg = new LoggerConfiguration()
|
||||
var logCfg = _cfg
|
||||
.Enrich.FromLogContext()
|
||||
.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb)
|
||||
.Enrich.WithProperty("Component", _component)
|
||||
@ -53,6 +55,9 @@ namespace PluralKit.Core
|
||||
// Don't want App.Metrics/D#+ spam
|
||||
.MinimumLevel.Override("App.Metrics", LogEventLevel.Information)
|
||||
|
||||
// nor ASP.NET spam
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
|
||||
// Actual formatting for these is handled in ScalarFormatting
|
||||
.Destructure.AsScalar<SystemId>()
|
||||
.Destructure.AsScalar<MemberId>()
|
||||
|
Loading…
Reference in New Issue
Block a user