2
votes

We're using ServiceStack to build a web API. I have a situation where I want to be able to return a response of 400 (BadRequest) from an API endpoint with some additional data indicating the specific cause(s) of the error.

The two ways I know about to return a specific status code are:

  1. Throw an exception.
  2. Return an instance of HttpResult.

I'd rather not return an instance of HttpResult. It would require me to make the method return type more generic (currently the return type is the specific response DTO), and there are other reasons (having to do with our use of ServiceStack) why that is problematic.

The situation with throwing an exception is weird. Based on the form of the response, ServiceStack is using the custom DTO even in the exception case (and the docs confirm this). And the HttpError exception class has a Response property which corresponds to the DTO used to issue the response, but setting the Response property to an instance of the custom DTO does not have the intended effect. It only affects the value of the ResponseStatus property on the response DTO. The other properties on the DTO are uninitialized as though ServiceStack generated a fresh instance of of the response DTO and used that instead (but set its ResponseStatus property from the provided DTO.

Is everything I've said actually correct? Is there another option for forming the response that doesn't have the drawbacks I've mentioned above?

1

1 Answers

2
votes

If you want to decorate a Response with additional metadata, return the response in a HttpResult - that's the entire purpose of the class. There's no visible difference to the HTTP Response body of a Response DTO returned directly vs wrapped in a HttpResult.

Alternatively you can just modify the base.Response directly, see the docs on Customizing HTTP Responses.

Throwing an Exception is only returning a HTTP Error Response. ServiceStack has implicit structured error handling where it captures the Error in a ResponseStatus which is extracted from any Response DTO.