Skip to content

Commit d5d101f

Browse files
Standardize API error responses with RFC 7807 ProblemDetails
- Add NotFoundProblem() helper to base controller for consistent 404 responses - Add global ProducesResponseType for 500 errors on base controller - Update GetByKeyIssueController to return IActionResult with proper NotFound - Update DeleteAuditController to return ProblemDetails on NotFound 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ca88170 commit d5d101f

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

src/Umbraco.Community.ContentAudit/Api/Audit/DeleteAuditController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ public DeleteAuditController(IDataService dataService) : base(dataService) { }
2121
/// <param name="id">Audit unique identifier.</param>
2222
[HttpDelete("{id:guid}")]
2323
[ProducesResponseType(StatusCodes.Status200OK)]
24-
[ProducesResponseType(StatusCodes.Status404NotFound)]
25-
public async Task<ActionResult> Delete(Guid id)
24+
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
25+
public async Task<IActionResult> Delete(Guid id)
2626
{
2727
var result = await DataService.DeleteAudit(id);
28-
return result ? Ok() : NotFound();
28+
return result ? Ok() : NotFoundProblem("Audit", id);
2929
}
3030
}
3131
}

src/Umbraco.Community.ContentAudit/Api/ContentAuditManagementApiControllerBase.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.AspNetCore.Mvc;
1+
using Microsoft.AspNetCore.Http;
2+
using Microsoft.AspNetCore.Mvc;
23
using Umbraco.Cms.Api.Common.Attributes;
34
using Umbraco.Community.ContentAudit.Api.Audit;
45

@@ -12,15 +13,34 @@ namespace Umbraco.Community.ContentAudit.Api
1213
/// - Maps all derived controllers to the "content-audit" API namespace
1314
/// - Applies [ApiController] attribute for automatic model validation and binding
1415
/// - Inherits from <see cref="Controller"/> to provide standard MVC controller functionality
15-
///
16+
///
1617
/// All Content Audit API controllers should derive from this base class either directly
1718
/// or through intermediate base classes like <see cref="AuditControllerBase"/>.
18-
///
19+
///
1920
/// The [MapToApi] attribute ensures all endpoints are properly routed under the
2021
/// "/umbraco/content-audit/management/api/v1/" path prefix.
2122
/// </remarks>
2223
[ApiController]
2324
[MapToApi("content-audit")]
25+
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
2426
public class ContentAuditManagementApiControllerBase : Controller
25-
{ }
27+
{
28+
/// <summary>
29+
/// Creates a NotFound response with RFC 7807 ProblemDetails.
30+
/// </summary>
31+
/// <param name="resourceType">The type of resource that was not found.</param>
32+
/// <param name="id">The identifier that was searched for.</param>
33+
protected NotFoundObjectResult NotFoundProblem(string resourceType, Guid id)
34+
{
35+
var problemDetails = new ProblemDetails
36+
{
37+
Status = StatusCodes.Status404NotFound,
38+
Title = $"{resourceType} not found",
39+
Detail = $"No {resourceType.ToLowerInvariant()} with id '{id}' was found.",
40+
Type = "https://tools.ietf.org/html/rfc7807",
41+
Instance = HttpContext?.Request.Path
42+
};
43+
return NotFound(problemDetails);
44+
}
45+
}
2646
}

src/Umbraco.Community.ContentAudit/Api/Issues/GetByKeyIssueController.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http;
12
using Microsoft.AspNetCore.Mvc;
23
using Umbraco.Community.ContentAudit.Interfaces;
34
using Umbraco.Community.ContentAudit.Models.Dtos;
@@ -20,8 +21,12 @@ public GetByKeyIssueController(IDataService dataService) : base(dataService) { }
2021
/// </summary>
2122
/// <param name="id">Issue unique identifier.</param>
2223
[HttpGet("{id:guid}")]
23-
[ProducesResponseType(typeof(IssueDto), 200)]
24-
public async Task<IssueDto?> GetIssue(Guid id)
25-
=> await DataService.GetIssue(id);
24+
[ProducesResponseType(typeof(IssueDto), StatusCodes.Status200OK)]
25+
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
26+
public async Task<IActionResult> GetIssue(Guid id)
27+
{
28+
var issue = await DataService.GetIssue(id);
29+
return issue != null ? Ok(issue) : NotFoundProblem("Issue", id);
30+
}
2631
}
2732
}

0 commit comments

Comments
 (0)