Skip to content

Add machine readable codes for validation errors #1189

@martivj

Description

@martivj

Description

In #1162 we listed potential candides for unique machine readable 400 Bad Request error codes for v2 (future) controllers. There is an argument to be made that we only need unique error codes for non-400 errors, but for consistency we should explore how we can implement such codes for validation as well.

The application currently returns ValidationProblemDetails, which differs from ProblemDetails in that we have an errors field that might include multiple validation errors per request. Also, since we are using several layers of validation (deserializing -> model attributes -> FluentValidation), we have potential for early exists where we don't catch all errors from FluentValidation in the response. Take this example, when using the /future/orders endpoint:

  1. Invalid input enum for contentType -> early exit when parsing:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "notificationOrderRequest": [
      "The notificationOrderRequest field is required."
    ],
    "$.recipient.recipientEmail.emailSettings.contentType": [
      "The JSON value could not be converted to Altinn.Notifications.Models.EmailContentTypeExt. Path: $.recipient.recipientEmail.emailSettings.contentType | LineNumber: 10 | BytePositionInLine: 28."
    ]
  },
  "traceId": "00-1f4fe102c1726625cc8b1aec92eb029b-5e652ca2240833c0-01"
}
  1. Empty string for idempotencyId -> triggers [Required] attribute in external model:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "IdempotencyId": [
      "The IdempotencyId field is required."
    ]
  },
  "traceId": "00-7174e08c4ffc9ffb0a12a0e42d6ad83b-cf3e698f3c9a5de3-01"
}
  1. Invalid input for conditionEndpoint/emailAddress -> triggers FluentValidation validator flow:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "ConditionEndpoint": [
      "ConditionEndpoint must be a valid absolute URI or null."
    ],
    "Recipient.RecipientEmail.EmailAddress": [
      "Invalid email address format."
    ]
  },
  "traceId": "00-17f6e2f25b8dcc2ffdedfd2c217d8a12-5f2cdb313675d88b-01"
}

Introducing unique codes for validation errors will involve choices about the return structure, how to map unique errors for the ValidationProblemDetails, etc.

We should ask for potential strategies from other teams that may have implemented something similar.

Metadata

Metadata

Labels

status/draftStatus: When you create an issue before you have enough info to properly describe the issue.

Projects

Status

🌞 Sprint

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions