Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
seungyongshim committed Feb 18, 2024
1 parent df3c090 commit a7bf70c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


## .Net 8에서 GlobalErrorHandling이 추가됨
* https://juliocasal.com/blog/Global-Error-Handling-In-AspNet-Core-APIs.html*
* https://www.milanjovanovic.tech/blog/global-error-handling-in-aspnetcore-8
* https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0#produce-a-problemdetails-payload-for-exceptions

Expand Down
18 changes: 14 additions & 4 deletions src/WebApplicationMinimalApi8/Dto/MessageDto.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
using FluentValidation;
using Swashbuckle.AspNetCore.Filters;

namespace WebApplicationMinimalApi8.Dto;

public record MessageDto
{
[SwaggerParameterExample]
public required string Body { get; init; }

public string Body { get; init; } = "안녕하신지";

}

public class MessageDtoValidator : AbstractValidator<MessageDto>
{
public MessageDtoValidator()
{
RuleFor(x => x.Body).NotEmpty();
RuleFor(x => x.Body).NotEmpty().NotNull();
}
}
}

public class MessageDtoExmaple : IMultipleExamplesProvider<MessageDto>
{
public IEnumerable<SwaggerExample<MessageDto>> GetExamples()
{
yield return SwaggerExample.Create("빈값", new MessageDto { Body = "" });
yield return SwaggerExample.Create("null", new MessageDto { Body = null });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Diagnostics;
using System.Text.Json.Nodes;
using System.Text.Json;

namespace WebApplicationMinimalApi8.EndpointFilters;

public class ResponseAddTraceIdFilter : IEndpointFilter
{
public static JsonNode AddTraceId(object? value, string id)
{
var root = JsonSerializer.SerializeToNode(value)!.Root;

root["traceId"] = id;

return root;
}

public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
{
var id = Activity.Current?.Id ?? context.HttpContext.TraceIdentifier;
var ret = await next(context);

return ret switch
{
IStatusCodeHttpResult c => c switch
{
IValueHttpResult v => Results.Text(AddTraceId(v.Value, id).ToJsonString(), "application/json", statusCode: c.StatusCode),
{ } v => v
},
_ => ret
};
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Diagnostics;
using System.Text.Json;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Mvc;

Expand All @@ -9,23 +11,17 @@ public sealed class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logge
{
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
var traceId = Activity.Current?.Id ?? httpContext.TraceIdentifier;
logger.LogError(exception, "Exception occurred: {Message}", exception.Message);

var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = exception.Message,
};

httpContext.Response.StatusCode = problemDetails.Status.Value;

await httpContext.Response.WriteAsJsonAsync
(
value: problemDetails,
options: new(JsonSerializerDefaults.Web),
contentType: "application/problem+json",
cancellationToken
);
await Results.Problem(
title: exception.Message,
statusCode: StatusCodes.Status500InternalServerError,
extensions: new Dictionary<string, object?>
{
["traceId"] = traceId
}
).ExecuteAsync(httpContext);

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/WebApplicationMinimalApi8/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using WebApplicationMinimalApi8.Dto;
using WebApplicationMinimalApi8.EndpointFilters;
using WebApplicationMinimalApi8.ExceptionHandlers;

var builder = WebApplication.CreateBuilder(args);
Expand Down Expand Up @@ -35,8 +36,8 @@

app.MapPost("/validate", (MessageDto message) => message)
.WithDescription("메시지를 검증합니다.")

.AddFluentValidationFilter()
.AddEndpointFilter<ResponseAddTraceIdFilter>()
.WithOpenApi();

app.MapGet("/500", () =>
Expand Down

0 comments on commit a7bf70c

Please sign in to comment.