feat(api): surface 403/404/409 responses via middleware and docs

This commit is contained in:
2026-10-10 14:58:01 +02:00
parent 315dee2f6c
commit c5a43ef2a0
3 changed files with 15 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ public sealed class DocumentsController(ISender sender) : ControllerBase
[HttpGet("{id}")] [HttpGet("{id}")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAsync([FromRoute] string id, CancellationToken cancellationToken) public async Task<IActionResult> GetAsync([FromRoute] string id, CancellationToken cancellationToken)
{ {

View File

@@ -46,6 +46,9 @@ public sealed class WorkflowsController(ISender sender) : ControllerBase
[HttpPost("{wisagId:int}/{source}/{processId:int}/closing")] [HttpPost("{wisagId:int}/{source}/{processId:int}/closing")]
[ProducesResponseType(typeof(ApiEnvelope<CloseWorkflowResult>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiEnvelope<CloseWorkflowResult>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status403Forbidden)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status409Conflict)]
[ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ApiEnvelope<object>), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ApiEnvelope<CloseWorkflowResult>>> CloseAsync( public async Task<ActionResult<ApiEnvelope<CloseWorkflowResult>>> CloseAsync(
[FromRoute] int wisagId, [FromRoute] int wisagId,

View File

@@ -1,3 +1,4 @@
using DigitalData.TaskFlow.Application.Common.Exceptions;
using DigitalData.TaskFlow.Application.Common.Factories; using DigitalData.TaskFlow.Application.Common.Factories;
using DigitalData.TaskFlow.Domain.Common; using DigitalData.TaskFlow.Domain.Common;
using DigitalData.TaskFlow.Domain.Enums; using DigitalData.TaskFlow.Domain.Enums;
@@ -23,6 +24,16 @@ public sealed class ExceptionHandlingMiddleware(RequestDelegate next, ILogger<Ex
{ {
await next(context); await next(context);
} }
catch (ApiException apiException)
{
logger.LogWarning(apiException, "API exception intercepted.");
context.Response.StatusCode = apiException.StatusCode;
context.Response.ContentType = "application/json";
var response = ApiEnvelopeFactory.Create<object?>(null, apiException.MetaCode, apiException.Message);
await context.Response.WriteAsync(JsonSerializer.Serialize(response, JsonOptions));
}
catch (ValidationException validationException) catch (ValidationException validationException)
{ {
logger.LogWarning(validationException, "Validation failed."); logger.LogWarning(validationException, "Validation failed.");