Scottie
Scottie

Reputation: 545

How to control presence of OData error details

I'm trying to control the presence of details in error responses from a Web API 2 OData v4 service. When I hit the OData service hosted on my local IIS, I get something like this:

{
  "error": {
    "code": "Error code",
    "message": "Message from exception filter",
    "details": [
      {
        "code": "Detail code",
        "message": "Details here"
      }
    ],
    "innererror": {
      "message": "Exception message here",
      "type": "Exception type",
      "stacktrace": "Stack trace here"
    }
  }
}

When I take the same service and deploy it on a remote server, and hit it with the same message, I get this:

{
  "error": {
    "code": "Error code",
    "message": "Message from exception filter"
  }
}

I'm guessing that the "innererror" and "details" sections are suppressed because I'm calling the service remotely? I'm happy that the "innererror" section is suppressed - I don't want to leak those details - but I want to expose the "details" section so that I can provide some more feedback on certain errors. Is there a simple way to achieve this?

Thanks!

Upvotes: 0

Views: 1396

Answers (1)

Scottie
Scottie

Reputation: 545

I was creating my OData error responses using Request.CreateErrorResponse(myHttpStatusCode, myODataError). Looking at the source code of System.Web.Http.OData.Extensions.HttpRequestMessageExtensions.CreateErrorResponse, it appears that if Request.ShouldIncludeErrorDetail is false, then the ODataError is recreated with just the "code" and "message" items. My solution was to create another overload/extension of CreateErrorResponse which accepts a parameter that controls whether the details section should be included:

public static HttpResponseMessage CreateErrorResponse(this HttpRequestMessage request,
            HttpStatusCode statusCode, ODataError oDataError, bool includeDetails)
{
    if (request.ShouldIncludeErrorDetail())
    {
        return request.CreateResponse(statusCode, oDataError);
    }
    else
    {
        return request.CreateResponse(
            statusCode,
            new ODataError()
            {
                ErrorCode = oDataError.ErrorCode,
                Message = oDataError.Message,
                Details = includeDetails ? oDataError.Details : null
            });
    }
}

This allows the "innererror" section to be suppressed independently of the "details" section.

Upvotes: 2

Related Questions