Tag: NPE

  • IllegalStateException: Content has been consumed

    When working with Android or (to be more general) Apache HttpComponents, one should keep in mind that it depends on the HttpResponses (Api: Apache, Android) if they can be consumed multiple times or not. And if the response is not, then better triple check your code, what you’re doing.

    I experiences the (very ugly) issue during the apparently simple task of reading the content of the response. )For ease of simplicity, I also use Apache commons-io, to read buffers etc.)

    HttpResponse response = ...;
    String content = IOUtils.toString(response.getEntity().entity.getContent());

    Okay, how many possible Nullpointer Exceptions do you see? I didn’t care until I experienced the first one, so I made the code NPE safe:

    HttpEntity entity = response.getEntity();
    // entity can be null according to the docs!
    if (entity != null) { 
        // The interface doesn't say that getContent() MUST return non-null
        InputStream stream = entity.getContent(); 
            if (stream != null) {
                tempContent = IOUtils.toString(entity.getContent());
            }
    }

    And suddenly I was faced with IllegalStateException: Content has been consumed. As I also did changes somewhere else, I assumed the error in some toString()-Methods that would read the content of the response during debugging. But as the error also showed up without debugging, I had a closer look to my “improvement”.

    Well, the error was the call IOUtils.toString(entity.getContent()); which tried to re-aquire the Input Stream. But as I just aquired it two lines above for the null check, the content was already marked as consumed. So the (now hopefully) correct and robust code is:

    HttpEntity entity = response.getEntity();
    // entity can be null according to the docs!
    if (entity != null) { 
        // The interface doesn't say that getContent() MUST return non-null
        InputStream stream = entity.getContent(); 
            if (stream != null) {
                tempContent = IOUtils.toString(<strong>stream</strong>);
            }
    }

    And the moral of the story

    Be very carefull when reading HttpResponses! Also avoid pretty-printing the content in toString() – this might suddenly also consume your content. And good luck finding the point where you consume the content in such cases.

    But .. why?! Please avoid returning null!

    Yet I still wonder, why so many methods are allowed to return null instead of just an empty stream or something. All the Null-checks don’t make the code more readable. Some programmers might even be tempted to simply put an catch(NullPointerException e) around the part of

    response.getEntity().entity.getContent()

    . Nothing I’d really recommend but I could also understand if I’d see something in other code.