Reputation: 1132
I'm trying to get error response body in onFailure(RetrofitError error)
, but getting null
.
I am using the header Accept: text/plain
for requests and from response I receive Content-Type: text/plain
and can see body as text if I set LogLevel.FULL
. Moreover, error.getResponse().getStatus()
gives me correct status code.
But when I perform error.getBody()
or error.getResponse.getBody()
it returns null
. Inside error
I see that successType
is java.lang.String
, so I assume it should give me String
, but error.getCause()
shows me
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 6 path $
Also, error.getKind()
is CONVERSION
, which stands for
/** An exception was thrown while (de)serializing a body. */
but I expect to get kind as HTTP
Question is why does it tries to convert into JSON when all headers are using text/plain
and successType
is String
?
I need to get my response as plain text.
Code snippet:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(url)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new CustomOkHttpClient())
.setRequestInterceptor(new TransactionsRequestInterceptor())
.build();
TransactionsRestClient httpClient = restAdapter.create(TransactionsRestClient.class);
httpClient.createNewTransaction(request, new retrofit.Callback<String>() {
@Override
public void success(String transactionId, Response response) {
}
@Override
public void failure(RetrofitError error) {
// error.getBody() is null
}
}
public interface TransactionsRestClient {
@POST("/transactions")
void createNewTransaction(@Body TransactionRequest request, Callback<String> transactionId);
}
public class TransactionsRequestInterceptor implements RequestInterceptor {
@Override
public void intercept(RequestFacade request) {
request.addHeader(HOST, host);
request.addHeader(TOKEN, token);
request.addHeader(ACCEPT, TEXT);
request.addHeader(CONTENT_TYPE, JSON);
}
Logged requests/responses:
---> HTTP POST $url
Host: $host
Accept: text/plain
Content-Type: application/json
Content-Length: 133
$request_body
---> END HTTP (133-byte body)
<--- HTTP 202 $url //202 is expected
Access-Control-Allow-Origin:
Content-Type: text/plain
Date: Wed, 20 May 2015 16:08:46 GMT
Server: spray-can/1.3.1
Content-Length: 50
Connection: keep-alive
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1432138139875
OkHttp-Received-Millis: 1432138140004
The record for test10 is not currently authorized. // this is body I have to get
<--- END HTTP (50-byte body)
Thanks.
Upvotes: 0
Views: 3647
Reputation: 5986
In your code new RestAdapter.Builder()
you do not specify a Converter (setConverter()
).
Looking at Retrofit code, more specifically at RestAdapter and Platform I checked that if you do not specify a Converter it will use GSON as default:
@Override Converter defaultConverter() {
return new GsonConverter(new Gson());
}
I believe the solution is to create a Custom Converter (extending Converter class) and do nothing with your response, just returning the raw String.
Here's an example on how to create your own Converter.
Upvotes: 1
Reputation: 5986
By default Retrofit reads the response as a JSON and parses it automatically. You have to change it's default behavior.
This blog post might be helpful, and suggests you to get your String response as:
new String(((TypedByteArray) response.getBody()).getBytes());
Upvotes: 1