Refit: [BUG] Empty Response 202

Created on 9 Feb 2021  路  15Comments  路  Source: reactiveui/refit

Describe the bug
Returning accept from ApiGateway. Before I had method similar to this
Task<ApiResponse<object>> CreateMobileUserAccount(CreateUserRequest createUserRequest);

upgrade to latest refit and now I am getting
Refit.ApiException : An error occured deserializing the response.
---- System.Text.Json.JsonException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
-------- System.Text.Json.JsonReaderException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. LineNumber: 0 | BytePositionInLine: 0.

question

All 15 comments

I'm guessing the JSON invalid and/or isn't being parsed correctly by System.Text.Json. Please see the breaking changes in 6.0 and file a new issue if still an issue with Newtonsoft.

https://github.com/reactiveui/refit#breaking-changes-in-6x

GitHub
The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface. - reactiveui/refit

@clairernovotny

thanks. I think it is a issue with System.Text.Json. I am use the alternative package and it is working.

I would check your JSON. Based on the error, it's likely malformed and System Text Json is much stricter than Newtonsoft.

There is nothing wrong with my json. I am doing a Post and i am returning 202 with an empty response. With Newtonsfot Json it works fine

Re-opening as with the response type of ApiResponse, you're right, it shouldn't be deserializing anything.

would be good if it can be fixed

I see the issue -- I missed it initially due to GitHub formatting. ApiResponse<object> will try to deserialize something... and an empty string is not a valid JSON object. So the behavior is correct in that System.Text.Json is throwing as it's not a Json
response. Seems like Newtonsoft handles this differently.

If there's no expected JSON response, you can use HttpResponseMessage as the return type: Task<HttpResponseMessage> CreateMobileUserAccount(CreateUserRequest createUserRequest);

And that'll give you all the information you need.

Is there some other reason you were using ApiResponse<object>?

Alternatively, if you don't need to know the exact status code of the response, you could just return Task from your method:

Task CreateMobileUserAccount(CreateUserRequest createUserRequest);

_Note that this will also throw on an error status code, which may or may not be what you want._

@clairernovotny

I was using ApiResponse because I did not know I could use HttpResponseMessage

I will try with HttpResponseMessage.

@bennor I am writing integration tests and I want to assert of the HttpStatusCode returned

Hi all,
I have a similar issue in another case.
I am consulting an API that returns a 200 response with a json payload during a GET request, so I created a Refit API as follows:

[Get("/api/balance/{id}")]
 Task<IApiResponse<Balance>> GetBalanceAsync(int id)

The problem is that sometimes this API returns a NoContent (204) response with an empty content, so I get the same System.Text.Json.JsonException.

Is there a way that I can handle this without using a try/catch block or changing the method return to HttpResponseMessage?

I don't think so -- because the API is not returning a JSON object. If you're telling it to get an object back, it wants an object back.

Thanks @clairernovotny. I will deal with this response in my application.

@clairernovotny Quick question on the last part here, as I just ran into the issue with an API that is returning a 204, but by the virtue of it being a 204 response wouldn't the right thing for Refit to do be to return null or default as 204 means that there is no content and that there shouldn't be anything to try and deserialize?

@acgritt agreed that would have been nice... I had to change many interface to use HttpResponseMessage... but it works...

@ekjuanrejon My only concern with that option is that it then doesn't make use of the Serializer that is configured for Refit and you would have to have a separate configuration. The other option of a try/catch just feels dirty, especially when looking for a JsonException specifically vs an ApiException.

Was this page helpful?
0 / 5 - 0 ratings