bustoutsolutions / siesta

The civilized way to write REST API clients for iOS / macOS
https://bustoutsolutions.github.io/siesta/
MIT License
2.19k stars 159 forks source link

Cannot parse server response for status code 204 on delete request #245

Open edwardmp opened 6 years ago

edwardmp commented 6 years ago

Hi,

I really like this library, thanks for creating this!

Noticed a small issue today. I have an API which responds with a 204 (no content) status code on a successful DELETE request and thus has no content in the response body. This makes sense to me. However Siesta considers this to be an error Cannot parse server response.

Is this intended behavior? This issue is similar to #11 except that issue was concerning a POST request, not a DELETE request.

P.s. I made sure my API does not set a Content-Type header.

edwardmp commented 6 years ago

Hi @pcantrell do you have any suggestion for a workaround?

pcantrell commented 6 years ago

The “Cannot parse server response” error means that something in the transformer pipeline returned an error. If you look in the logs, there should be an accompanying underlying error. (You may need to enable more Siesta log categories to get the full info.)

Two likely causes:

In either case, one blanket solution is to disable the entire response transformer pipeline for all DELETE requests:

service.configure("**", requestMethods: [.delete]) {
  $0.removeAllTransformers()
}

Make sure to do that after configuring your own specific transformers. Siesta applies configuration in the order you specify it.

(You might want to only disable process for specific pipeline stages if you have some transformers that do useful things with headers, errors, etc.)

If it is one of your model transformers that is failing, another less ham-handed approach is to configure your model transformer only for specific request methods:

service.configureTransformer("/users/*", requestMethods: [.get, .put, .post]) {
    try jsonDecoder.decode(User.self, from: $0.content)
}
edwardmp commented 6 years ago

Hi @pcantrell,

Thanks for the reply!

The error is:

Details: failure userMessage: "Cannot parse server response" cause: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.})))

So the response has a 204 status code, the body is blank and the Content Type is not JSON. The last workaround you suggested works great, but it's still a workaround.

What I can't derive from your answer is whether this is expected behavior or a bug? It does not seem logical to me that if setting a 204 status code it still attempts to parse the body.

pcantrell commented 6 years ago

You need to look up above that in the log, where the transformer pipeline is being applied to the response. If you enable logging for configuration, network, and pipeline (the detailed preset includes all three), Siesta will show you what transformers are configured, what response the server sends back, and which transformers it applies to the response in what order. Look in the logs for entries matching those categories.

The question here is why it’s trying to apply a transformer that expects JSON. Is it because the server sent a content type that triggered default JSON parsing? Is it because you configured a model transformer that's kicking in?