2
votes

I have developed a custom exception which I throw from my ServiceStack service. The status code and description are mapped correctly, but the inner 'statusCode' value always appears to be '0'.

Here is how I have implemented my exception:

public class TestException : Exception, IHasStatusCode, IHasStatusDescription, IResponseStatusConvertible
{
    private readonly int m_InternalErrorCode;
    private readonly string m_ArgumentName;
    private readonly string m_DetailedError;


    public int StatusCode => 422;
    public string StatusDescription => Message;

    public TestException(int internalErrorCode, string argumentName, string detailedError)
        : base("The request was semantically incorrect or was incomplete.")
    {
        m_InternalErrorCode = internalErrorCode;
        m_ArgumentName = argumentName;
        m_DetailedError = detailedError;
    }

    public ResponseStatus ToResponseStatus()
    {
        return new ResponseStatus
        {
            ErrorCode = StatusCode.ToString(),
            Message = StatusDescription,
            Errors = new List<ResponseError>
            {
                new ResponseError
                {
                    ErrorCode = m_InternalErrorCode.ToString(),
                    FieldName = m_ArgumentName,
                    Message = m_DetailedError
                }
            }
        };
    }
}

When I throw my exception from my ServiceStack service
throw new TestException(123, "Thing in error", "Detailed error message");
I get a HTTP status code of 422 with a corresponding description (reason/phrase) set as expected when I view the response in my client (browser/postman etc), but the content (when I specify ContentType=application/json in the header) looks like this...

{
  "statusCode": 0,
  "responseStatus": {
    "errorCode": "422",
    "message": "The request was semantically incorrect or was incomplete.",
    "stackTrace": "StackTrace ommitted for berivity",
    "errors": [
      {
        "errorCode": "123",
        "fieldName": "Thing in error",
        "message": "Detailed error message"
      }
    ]
  }
}

As you can see in the json response above, the status code is '0'. My question is - how do I set this value? I am guessing that it should be the same as that of the the HTTP response (422 in the example above).

Update: Thanks to Mythz for pointing me to the answer I updated my response base class like this:

public abstract class ResponseBase : IHasResponseStatus, IHasStatusCode
{
    private int m_StatusCode;

    public int StatusCode
    {
        get
        {
            if (m_StatusCode == 0)
            {
                if (ResponseStatus != null)
                {
                    if (int.TryParse(ResponseStatus.ErrorCode, out int code))
                        return code;
                }
            }
            return m_StatusCode;
        }
        set
        {
            m_StatusCode = value;
        }
    }

    public ResponseStatus ResponseStatus { get; set; }
}
1

1 Answers

2
votes

ServiceStack only populates the ResponseStatus DTO in Error Responses, the statusCode property inside your Response DTO is an irrelevant property (likely on your Response DTO) that ServiceStack doesn't handle. The StatusCode property from IHasStatusCode interface implemented in Custom Exceptions is only used to populate HTTP Status Code.