diff --git a/src/com/loopj/android/http/AsyncHttpResponseHandler.java b/src/com/loopj/android/http/AsyncHttpResponseHandler.java index b17353063..4ea36bf7d 100644 --- a/src/com/loopj/android/http/AsyncHttpResponseHandler.java +++ b/src/com/loopj/android/http/AsyncHttpResponseHandler.java @@ -23,7 +23,6 @@ import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; -import org.apache.http.client.HttpResponseException; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.util.EntityUtils; @@ -193,20 +192,24 @@ protected Message obtainMessage(int responseMessage, Object response) { // Interface to AsyncHttpRequest void sendResponseMessage(HttpResponse response) { StatusLine status = response.getStatusLine(); + String responseBody = null; + try { + HttpEntity entity = null; + HttpEntity temp = response.getEntity(); + if(temp != null) { + entity = new BufferedHttpEntity(temp); + } + responseBody = EntityUtils.toString(entity); + } catch(IOException e) { + sendFailureMessage(e); + } + if(status.getStatusCode() >= 300) { - sendFailureMessage(new HttpResponseException(status.getStatusCode(), status.getReasonPhrase())); + sendFailureMessage(new HttpResponseException(status.getStatusCode(), + status.getReasonPhrase(), + responseBody)); } else { - try { - HttpEntity entity = null; - HttpEntity temp = response.getEntity(); - if(temp != null) { - entity = new BufferedHttpEntity(temp); - } - - sendSuccessMessage(EntityUtils.toString(entity)); - } catch(IOException e) { - sendFailureMessage(e); - } + sendSuccessMessage(responseBody); } } -} \ No newline at end of file +} diff --git a/src/com/loopj/android/http/HttpResponseException.java b/src/com/loopj/android/http/HttpResponseException.java new file mode 100644 index 000000000..3f4806f4f --- /dev/null +++ b/src/com/loopj/android/http/HttpResponseException.java @@ -0,0 +1,35 @@ +/* + Android Asynchronous Http Client + Copyright (c) 2011 James Smith + http://loopj.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.loopj.android.http; + +/** + * Custom exception class, that inherits from + * org.apache.http.client.HttpResponseException, but includes HTTP response body. + */ +public class HttpResponseException extends org.apache.http.client.HttpResponseException { + private String responseBody = null; + public HttpResponseException(int statusCode, String s, String responseBody) { + super(statusCode, s); + this.responseBody = responseBody; + } + + public String getResponseBody() { + return responseBody; + } +} diff --git a/src/com/loopj/android/http/JsonHttpResponseHandler.java b/src/com/loopj/android/http/JsonHttpResponseHandler.java index 51c2093eb..bd1b227cc 100644 --- a/src/com/loopj/android/http/JsonHttpResponseHandler.java +++ b/src/com/loopj/android/http/JsonHttpResponseHandler.java @@ -57,6 +57,21 @@ public void onSuccess(JSONObject response) {} */ public void onSuccess(JSONArray response) {} + /** + * Fired when a request fails to complete but valid JSON response body was + * returned by server, override to handle in your own code. + * @param error the underlying cause of the failure + * @param response response the parsed json object found in the server response (if any) + */ + public void onFailure(Throwable error, JSONObject response) {} + + /** + * Fired when a request fails to complete but valid JSON response body was + * returned by server, override to handle in your own code. + * @param error the underlying cause of the failure + * @param response response the parsed json array found in the server response (if any) + */ + public void onFailure(Throwable error, JSONArray response) {} // Utility methods @Override @@ -75,6 +90,25 @@ protected void handleSuccessMessage(String responseBody) { } } + // Utility methods + protected void handleFailureMessage(Throwable e) { + super.handleFailureMessage(e); + + if (e.getClass() == com.loopj.android.http.HttpResponseException.class) { + try { + Object jsonResponse = parseResponse(((HttpResponseException) e).getResponseBody()); + if(jsonResponse instanceof JSONObject) { + onFailure(e, (JSONObject)jsonResponse); + } else if(jsonResponse instanceof JSONArray) { + onFailure(e, (JSONArray)jsonResponse); + } + } catch(JSONException je) { + onFailure(je); + } + } + onFailure(e); + } + protected Object parseResponse(String responseBody) throws JSONException { return new JSONTokener(responseBody).nextValue(); }