Is there a way to get to the original http post message from onfailure of okhttp3?

Viewed 54
    Request request = new Request.Builder()
            .url("http://example.com")
            .post(RequestBody.create("foo",MediaType.get("text/plain")))
            .build();
client.newCall(request).enqueue(new Callback() {
             
                @Override
                public void onFailure(Call call, IOException e) {
                    //e.printStackTrace();
                    RequestBody b = call.request().body();
                    String t= b.toString(); ??? <-How would I get the original message?
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    //do something
                     
                }
            });

On failure I am trying to save the original message that I sent.

I looked through the functions and I don't seem to be able to figure out how to get the original message I sent in the callback. Is there a way to get the message back?

2 Answers

In case anyone is looking for this:

Buffer b = new Buffer();
call.request().body().writeTo(b)
String result=b.readString(Charset.defaultCharset()); //Change this to whatever your character set is

In addition to your answer, you could define an Interceptor and log those requests who failed. This as example, without any conditions:

class ReqInterceptor implements Interceptor 
{
   @Override
   public Response intercept(Interceptor.Chain chain) throws IOException
   {
     Request request = chain.request();  // original Request
     logger.info(String.format("Sending request %s on %s%n%s",
                 request.url(), chain.connection(), request.headers()));

     Response response = chain.proceed(request);
     logger.info(String.format("Received response for %s %s",
                 response.request().url(), response.headers()));
   
     return response;
   }
}

Then in the client, something like:

OkHttpClient client = new OkHttpClient.Builder()
            .addNetworkInterceptor(new ReqInterceptor()) //<--this
            .build();

Request request = new Request.Builder()
        .url("http://example.com")
        .post(RequestBody.create("foo",MediaType.get("text/plain")))
        .build();

Response response = client.newCall(request).execute();
response.body().close();

There are two types and even two defined implementations for Interceptor, but the network one would provide the same data that is transmitted by the wire, so you may choose this if exact info is needed:

enter image description here

Related