Skip to content

Commit 6fe5ce6

Browse files
committed
Refactor preserving call chain for backward compatibility
1 parent 2988325 commit 6fe5ce6

File tree

9 files changed

+487
-452
lines changed

9 files changed

+487
-452
lines changed

library/src/com/loopj/android/http/AsyncHttpClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ private HttpEntity paramsToEntity(RequestParams params, AsyncHttpResponseHandler
889889
}
890890
} catch (Throwable t) {
891891
if (responseHandler != null)
892-
responseHandler.sendFailureMessage(0, null, t, (String) null);
892+
responseHandler.sendFailureMessage(0, null, (byte[]) null, t);
893893
else
894894
t.printStackTrace();
895895
}

library/src/com/loopj/android/http/AsyncHttpRequest.java

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -38,118 +38,88 @@ class AsyncHttpRequest implements Runnable {
3838
private final HttpContext context;
3939
private final HttpUriRequest request;
4040
private final AsyncHttpResponseHandler responseHandler;
41-
private boolean isBinaryRequest;
4241
private int executionCount;
4342

4443
public AsyncHttpRequest(AbstractHttpClient client, HttpContext context, HttpUriRequest request, AsyncHttpResponseHandler responseHandler) {
4544
this.client = client;
4645
this.context = context;
4746
this.request = request;
4847
this.responseHandler = responseHandler;
49-
if (responseHandler instanceof BinaryHttpResponseHandler) {
50-
this.isBinaryRequest = true;
51-
}
5248
}
5349

5450
@Override
5551
public void run() {
56-
try {
57-
if (responseHandler != null) {
58-
responseHandler.sendStartMessage();
59-
}
52+
if (responseHandler != null) {
53+
responseHandler.sendStartMessage();
54+
}
6055

56+
try {
6157
makeRequestWithRetries();
62-
63-
if (responseHandler != null) {
64-
responseHandler.sendFinishMessage();
65-
}
6658
} catch (IOException e) {
6759
if (responseHandler != null) {
68-
responseHandler.sendFinishMessage();
69-
if (this.isBinaryRequest) {
70-
responseHandler.sendFailureMessage(e, (byte[]) null);
71-
} else {
72-
responseHandler.sendFailureMessage(e, (String) null);
73-
}
60+
responseHandler.sendFailureMessage(0, null, (byte[]) null, e);
7461
}
7562
}
63+
64+
if (responseHandler != null) {
65+
responseHandler.sendFinishMessage();
66+
}
7667
}
7768

78-
private void makeRequest() throws IOException, InterruptedException {
69+
private void makeRequest() throws IOException {
7970
if (!Thread.currentThread().isInterrupted()) {
80-
try {
81-
// Fixes #115
82-
if (request.getURI().getScheme() == null)
83-
throw new MalformedURLException("No valid URI scheme was provided");
84-
HttpResponse response = client.execute(request, context);
85-
if (!Thread.currentThread().isInterrupted()) {
86-
if (responseHandler != null) {
87-
responseHandler.sendResponseMessage(response);
88-
}
89-
} else {
90-
throw new InterruptedException("makeRequest was interrupted");
91-
}
92-
} catch (IOException e) {
93-
if (!Thread.currentThread().isInterrupted()) {
94-
throw e;
71+
// Fixes #115
72+
if (request.getURI().getScheme() == null) {
73+
// subclass of IOException so processed in the caller
74+
throw new MalformedURLException("No valid URI scheme was provided");
75+
}
76+
77+
HttpResponse response = client.execute(request, context);
78+
79+
if (!Thread.currentThread().isInterrupted()) {
80+
if (responseHandler != null) {
81+
responseHandler.sendResponseMessage(response);
9582
}
9683
}
9784
}
9885
}
9986

100-
private void makeRequestWithRetries() throws ConnectException {
101-
// This is an additional layer of retry logic lifted from droid-fu
102-
// See: https://github.com/kaeppler/droid-fu/blob/master/src/main/java/com/github/droidfu/http/BetterHttpRequestBase.java
87+
private void makeRequestWithRetries() throws IOException {
10388
boolean retry = true;
10489
IOException cause = null;
10590
HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();
106-
while (retry) {
107-
try {
108-
makeRequest();
109-
return;
110-
} catch (ClientProtocolException e) {
111-
if (responseHandler != null) {
112-
responseHandler.sendFailureMessage(e, "cannot repeat the request");
113-
}
114-
return;
115-
} catch (UnknownHostException e) {
116-
if (responseHandler != null) {
117-
responseHandler.sendFailureMessage(e, "can't resolve host");
91+
try
92+
{
93+
while (retry) {
94+
try {
95+
makeRequest();
96+
return;
97+
} catch (UnknownHostException e) {
98+
// switching between WI-FI and mobile data networks can cause a retry which then results in an UnknownHostException
99+
// while the WI-FI is initialising. The retry logic will be invoked here, if this is NOT the first retry
100+
// (to assist in genuine cases of unknown host) which seems better than outright failure
101+
cause = new IOException("UnknownHostException exception: " + e.getMessage());
102+
retry = (executionCount > 0) && retryHandler.retryRequest(cause, ++executionCount, context);
103+
} catch (NullPointerException e) {
104+
// there's a bug in HttpClient 4.0.x that on some occasions causes
105+
// DefaultRequestExecutor to throw an NPE, see
106+
// http://code.google.com/p/android/issues/detail?id=5255
107+
cause = new IOException("NPE in HttpClient: " + e.getMessage());
108+
retry = retryHandler.retryRequest(cause, ++executionCount, context);
109+
} catch (IOException e) {
110+
cause = e;
111+
retry = retryHandler.retryRequest(cause, ++executionCount, context);
118112
}
119-
return;
120-
} catch (ConnectTimeoutException e) {
121-
if (responseHandler != null) {
122-
responseHandler.sendFailureMessage(e, "connection timed out");
123-
}
124-
} catch (SocketException e) {
125-
// Added to detect host unreachable
126-
if (responseHandler != null) {
127-
responseHandler.sendFailureMessage(e, "can't resolve host");
113+
if(retry && (responseHandler != null)) {
114+
responseHandler.sendRetryMessage();
128115
}
129-
return;
130-
} catch (SocketTimeoutException e) {
131-
if (responseHandler != null) {
132-
responseHandler.sendFailureMessage(e, "socket time out");
133-
}
134-
return;
135-
} catch (IOException e) {
136-
cause = e;
137-
retry = retryHandler.retryRequest(cause, ++executionCount, context);
138-
} catch (NullPointerException e) {
139-
// there's a bug in HttpClient 4.0.x that on some occasions causes
140-
// DefaultRequestExecutor to throw an NPE, see
141-
// http://code.google.com/p/android/issues/detail?id=5255
142-
cause = new IOException("NPE in HttpClient" + e.getMessage());
143-
retry = retryHandler.retryRequest(cause, ++executionCount, context);
144-
} catch (InterruptedException e) {
145-
cause = new IOException("Request was interrupted while executing");
146-
retry = retryHandler.retryRequest(cause, ++executionCount, context);
147116
}
117+
} catch (Exception e) {
118+
// catch anything else to ensure failure message is propagated
119+
cause = new IOException("Unhandled exception: " + e.getMessage());
148120
}
149-
150-
// no retries left, crap out with exception
151-
ConnectException ex = new ConnectException();
152-
ex.initCause(cause);
153-
throw ex;
121+
122+
// cleaned up to throw IOException
123+
throw(cause);
154124
}
155125
}

0 commit comments

Comments
 (0)