feat(backend): restructure API into layers with OpenAPI, versioning and error handling
Split the backend into API host, Domain, Application and Infrastructure projects. Add Swagger/OpenAPI per API version, Asp.Versioning (query/header), ProblemDetails with a global exception handler and SurrealQL migrations applied at startup (namespace/database ensured). Infrastructure owns the SurrealDB client, settings and DI.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace TarninaHub.Errors;
|
||||
|
||||
public sealed class GlobalExceptionHandler : IExceptionHandler
|
||||
{
|
||||
private readonly ILogger<GlobalExceptionHandler> _logger;
|
||||
|
||||
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async ValueTask<bool> TryHandleAsync(
|
||||
HttpContext httpContext,
|
||||
Exception exception,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogError(exception, "Unhandled exception for {Method} {Path}",
|
||||
httpContext.Request.Method,
|
||||
httpContext.Request.Path);
|
||||
|
||||
var problem = new ProblemDetails
|
||||
{
|
||||
Type = "https://httpstatuses.io/500",
|
||||
Title = "An unexpected error occurred.",
|
||||
Status = StatusCodes.Status500InternalServerError,
|
||||
Instance = httpContext.Request.Path,
|
||||
};
|
||||
|
||||
httpContext.Response.StatusCode = problem.Status.Value;
|
||||
|
||||
await httpContext.Response.WriteAsJsonAsync(problem, cancellationToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user