Skip to main content

Dynamic Error Messages

While Custom Error Messages feature allows users to define static string against HTTP responses, it doesn't support a way to provide any information from the exception at runtime. For this purpose, we have introduced Dynamic Error Messages feature that allows you to define templated messages that populate placeholders at runtime.

Configure Dynamic Error Messages

Error templates are customized using a map structure that you can edit in the your OpenAPI specification file. These are configured at either endpoint level or globally; the syntax of both is shown below:

OpenAPI v3.0
// At endpoint level
"/pets": {
"post": {
...
"responses": {
"400": {
"description": "Static error message"
}
},
"x-operation-settings": {
"ErrorTemplates": {
"401": "Error message - {placeholder1} - {placeholder2}",
"403": "Error message - {placeholder1} - {placeholder3}",
"0": "Error message - {placeholder4}"
}
}
}
}
// Globally for all endpoints
"x-codegen-settings": {
"ErrorTemplates": {
"404": "Error message - {placeholder}"
}
}

In this map,

  • Error code: Must be a valid HTTP error status code. (4XX - 5XX)
  • Error message: The string you want as an error message.
  • Placeholder: Placeholder that is replaced by data from an exception at runtime.
  • 0: Runs in case of any undeclared error codes.

For example, here's an HTTP response header:

200 OK
Connection: Keep-Alive
Content-Type: text/html
Server: Apache

And its HTTP response body:

{
"category": "AUTHENTICATION_ERROR",
"description": "UNAUTHORIZED",
"detail": "The request could not be authorized."
}

From this response, you can use the properties connection, server, category and detail etc. as placeholders inside your message template to define dynamic HTTP error response. The available placeholders that can be used are listed below:

SourcePlaceholderDetailsExample
Status code$statusCodeUse this placeholder to add the status response code at runtime.{$statusCode}
Response header$response.header.header_keyUse this placeholder to add a key from response header.{$response.header.Content-Type}
Response body$response.body#/json_pointerUse this placeholder to add a parameter from the response body.{$response.body#/detail}

You can use any of these placeholders or a combination of them while defining error templates.

info

To populate these placeholders at runtime, we have extended the runtime expressions feature of OpenAPI specification that allows defining values based on objects of an HTTP message.

For example, here's how you can configure dynamic error message in your API specification:

OpenAPI v3.0
"ErrorTemplates": {
"401": "Response returned of status code - {$statusCode}, content type - {$response.header.Content-Type} and category - {$reponse.body#/category}"
}

Once you have configured dynamic error messages, you can catch the response in the API call.

try
{
petsController.CreatePet(pet);
}
catch (ApiException exception)
{
// Printing the error message
Console.WriteLine(exception.Message);
}

Through this configured message, SDK will surface the following error message:

Response returned of status code - 401, content type - text/html and category - AUTHENTICATION_ERROR.

For more details on how these error templates work, please refer to Error Templates in OpenAPI CodeGen Extensions.

Use Cases

The following scenarios cover multiple use cases of customizing error response messages.

Configure Single Error Message

Here's a simple configuration to customize an error message against one error code and its behavior.

OpenAPI v3.0
"ErrorTemplates": {
"403": "Response returned an error because {$response.body#/details}."
}

Behavior:

  • If the returned status code is 403, then the error message will be customized to:
    Response returned an error because client is forbidden from accessing the server.
  • In the case where the above mentioned placeholders are used incorrectly or the placeholder could not be resolved(for example when the response body JSON does not contain the specified property), then the returned response will be:
    Response returned an error because .
  • In the case where only one HTTP code is configured, if the returned code is anything other than 403, then the returned response will be:
    HTTP Response Not OK.

Configure Multiple Error Messages

Here's how you can configure multiple error messages at once.

OpenAPI v3.0
"ErrorTemplates": {
"400": "Response returned an error with status code {$statusCode}.",
"402": "Response returned an error of category {$response.body#/category} - {$response.body#/detail}"
}

Behavior:

  • If the error code is 400, then the error response will be:
    Response returned an error with status code 400.
  • If the error code is 402, then the error response will be:
    Response returned an error of category INVALID_PAYMENT - This call requires payment details. 
  • In this case where only selective codes are customized, if the returned error code is anything other than 400 or 402, then the error response will be:
    HTTP Response Not OK.

Configure Default Error Message

Here's how you can configure a default case that runs in case the returned error response is undeclared.

OpenAPI v3.0
"ErrorTemplates": {
"400": "Response returned an error with status code {$statusCode}.",
"402": "Response returned an error of category {$response.body#/category} - {$response.body#/detail}",
"0": "Response returned an error with status code {$statusCode}"
}

Behavior:

  • In this case, if the returned HTTP code is either 400 or 402, then the respective messages will be displayed.

  • In case the returned response is neither of these configured HTTP codes, then the returned response will be the message configured under 0 key.

Configure Error Messages for Error Range

To configure error messages for an entire error range (either 4XX or 5XX), you can mention the range instead of error status code in the ErrorTemplates.

OpenAPI v3.0
"ErrorTemplates": {
"4XX": "Response returned an error of category {$response.body#/category} and content type {$response.header.Content-Type}.",
"5XX": "Response returned an error with status code {$statusCode} and details: {$response.body#/detail}."
}

Behavior:

  • If the returned error code falls in the range 400 - 499, then the returned message will be:
    Response returned an error of category INVALID_PAYMENT and content type application/json.
  • If the returned error code falls in the range 500 - 599, then the returned message will be:
    Response returned an error with status code 501 and details: The request functionality is not supported.

Priority of Customized Error Messages

If both Custom Error Messages and Dynamic Error Messages have been configured, then the following priority decides which error message will be displayed:

  1. Highest priority will go to error template customized at endpoint level.
  2. Next is error response description customized at endpoint level.
  3. Last is error templates customized at global level.

For example, here's an OpenAPI specification file that has Custom Error Messages and Dynamic Error Messages configured:

OpenAPI v3.0
"/pets": {
"post": {
...
"responses": {
"400": {
"description": "Call failed due to bad request."
},
"403": {
"description": "Access is forbidden."
}
},
"x-operation-settings": {
"ErrorTemplates": {
"400": "Response returned an error with {$statusCode} - {$response.body#/detail}",
"401": "Response returned an error of {$response.body#/category} and content type {$response.header.Content-Type}"
}
}
}
}
...
"x-codegen-settings": {
"ErrorTemplates": {
"400": "Response returned an error with {$statusCode}",
"403": "Response returned an error because {$response.body#/detail}",
"404": "Response returned an error of category {$response.body#/category}",
"0": "Response returned an error because {$response.body#/detail}"
}
}

In this scenario:

  • In case of error 400, message configured under x-operation-settings will take precendence.
  • In case of error 403, message configured under error responses will take precedence.
  • In case of error 405, message configured for 0 in x-codegen-settings will be executed.