Skip to content

Updated error responses of the ResourceModificationController to be RFC 9457 compliant - #1444

Open
Liviafranke wants to merge 1 commit into
PHOENIXCONTACT:fix/update-resources-controllerfrom
Liviafranke:feature/rfc9457-error-responses
Open

Updated error responses of the ResourceModificationController to be RFC 9457 compliant#1444
Liviafranke wants to merge 1 commit into
PHOENIXCONTACT:fix/update-resources-controllerfrom
Liviafranke:feature/rfc9457-error-responses

Conversation

@Liviafranke

Copy link
Copy Markdown

Changes

Standardized Error Responses

All error responses returned by ResourceModificationController now use the RFC 9457 format with the following fields:

  • type
  • title
  • status
  • detail
  • instance
     
    Field descriptions:
  • type references the HTTP status code definition in RFC 9110.
  • title provides a localized summary of the error.
  • status contains the HTTP status code returned by the API.
  • detail provides a localized and more detailed description of the error.
  • instance contains the path of the request that triggered the error (HttpContext.Request.Path).

Controller Error Handling

Replaced MoryxExceptionResponse with ProblemDetails.
The controller only returns expected and explicity handled errors. For these scenarios, the standard ProblemDetails class is fully sufficient because no additional exception information is required. Therefore, MoryxExceptionResponse did not provide any additional value in this context.
MoryxExceptionResponse is still used by the global MoryxExceptionFilter, which handles unexpected exceptions and includes the exception field in the response body to support debugging.

Refactoring of MoryxExceptionResponse

MoryxExceptionResponse now inherits from ProblemDetails.
 
As a result:

  • The response model is aligned with RFC 9457.
  • The custom error title property has been removed, since ProblemDetails already provides the standardized title field.
  • Existing exception-specific information can still be included where required.

Localization

Added localization for the title and detail fields in English, German, Italian, Polish and Chinese.

…urceModificationController and added localization
@Liviafranke Liviafranke self-assigned this Aug 18, 2026
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

if (resourceModel is null)
return NotFound(new MoryxExceptionResponse { Title = string.Format(Strings.ResourceNotFoundException_ById_Message, id) });

return NotFound(new ProblemDetails

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to shorten this in an elegenat fashion. Something like

return NotFound().With(Title, Details, context)

Maybe @seveneleven has an opinion on this, designing fluent APIs is something of a habit of his 😁

If we go with the example above, you'd need to create extensions methods on, in this case, the NotFoundResult type, which returns a NotFoundObjectResult with the problemdetails object inside that you also used here. The result would be an easier to read return statement with less duplicated property assignements.

And then you would repeat that for BadRequest and any other standard error response code we are currenlty using 😊

Edit: For the resource not found response I'm also very sure, that you can further decrease code duplication if you define an extension method within this project which already has the other properties set as well.

Edit 2: I just saw there is a Problem(...) virtual method on the controller base class which already gets the context set. So my new suggestion for the fluent API is

// Placed in Moryx.AspNetCore project
return Problem().NotFound(Title, Details)

And within this project

return Problem().NotResourceFound(id)

Type = "https://www.rfc-editor.org/rfc/rfc9110.html#name-404-not-found",
Title = Strings.ResourceModificationController_ResourceNotFound_Title,
Status = StatusCodes.Status404NotFound,
Detail = string.Format(CultureInfo.CurrentCulture, Strings.ResourceModificationController_ResourceNotFoundException_ById_Message, id),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Detail = string.Format(CultureInfo.CurrentCulture, Strings.ResourceModificationController_ResourceNotFoundException_ById_Message, id),
Detail = string.Format(CultureInfo.CurrentCulture, Strings.ResourceModificationController_ResourceNotFound_ById_Message, id),

{
public string Title { get; set; }

public string Exception { get; set; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the RFC specifically states Problem details are not a debugging tool for the underlying implementation we should remove this type completely and should not return exception messages or stack traces from any endpoint.

Instead, we should log the exceptions in the endpoints together with a trace Id, which can be added to the problem details in the extensions. I think this is the place were we should start with providing an extension method to be used in the Program.cs as a central solution. Following is a minimal AI snippet for that. However, it does not include logging the exceptions in the controller or appending trace IDs only where there is actually a problem details response. So it only swerves as a starting point.

using System.Diagnostics;

builder.Services.AddProblemDetails(options =>
{
    options.CustomizeProblemDetails = context =>
    {
        context.ProblemDetails.Extensions["traceId"] =
            Activity.Current?.TraceId.ToString()
            ?? context.HttpContext.TraceIdentifier;
    };
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants