19
19
package com .loopj .android .http ;
20
20
21
21
import java .io .IOException ;
22
- import java .net .ConnectException ;
23
- import java .net .SocketException ;
24
- import java .net .SocketTimeoutException ;
25
22
import java .net .UnknownHostException ;
26
23
27
24
import org .apache .http .HttpResponse ;
@@ -49,26 +46,20 @@ public AsyncHttpRequest(AbstractHttpClient client, HttpContext context, HttpUriR
49
46
}
50
47
51
48
public void run () {
52
- try {
53
- if (responseHandler != null ){
54
- responseHandler .sendStartMessage ();
55
- }
49
+ if (responseHandler != null ) {
50
+ responseHandler .sendStartMessage ();
51
+ }
56
52
53
+ try {
57
54
makeRequestWithRetries ();
58
-
59
- if (responseHandler != null ) {
60
- responseHandler .sendFinishMessage ();
61
- }
62
55
} catch (IOException e ) {
63
- if (responseHandler != null ) {
64
- responseHandler .sendFinishMessage ();
65
- if (this .isBinaryRequest ) {
66
- responseHandler .sendFailureMessage (e , (byte []) null );
67
- } else {
68
- responseHandler .sendFailureMessage (e , (String ) null );
69
- }
56
+ if (responseHandler != null ) {
57
+ responseHandler .sendFailureMessage (0 , null , e );
70
58
}
71
59
}
60
+ if (responseHandler != null ) {
61
+ responseHandler .sendFinishMessage ();
62
+ }
72
63
}
73
64
74
65
private void makeRequest () throws IOException {
@@ -90,47 +81,44 @@ private void makeRequest() throws IOException {
90
81
}
91
82
}
92
83
93
- private void makeRequestWithRetries () throws ConnectException {
84
+ private void makeRequestWithRetries () throws IOException {
94
85
// This is an additional layer of retry logic lifted from droid-fu
95
86
// See: https://github.com/kaeppler/droid-fu/blob/master/src/main/java/com/github/droidfu/http/BetterHttpRequestBase.java
96
87
boolean retry = true ;
97
88
IOException cause = null ;
98
89
HttpRequestRetryHandler retryHandler = client .getHttpRequestRetryHandler ();
99
- while (retry ) {
100
- try {
101
- makeRequest ();
102
- return ;
103
- } catch (UnknownHostException e ) {
104
- if (responseHandler != null ) {
105
- responseHandler .sendFailureMessage (e , "can't resolve host" );
106
- }
107
- return ;
108
- }catch (SocketException e ){
109
- // Added to detect host unreachable
110
- if (responseHandler != null ) {
111
- responseHandler .sendFailureMessage (e , "can't resolve host" );
90
+ try
91
+ {
92
+ while (retry ) {
93
+ try {
94
+ makeRequest ();
95
+ return ;
96
+ } catch (UnknownHostException e ) {
97
+ // switching between WI-FI and mobile data networks can cause a retry which then results in an UnknownHostException
98
+ // while the WI-FI is initialising. The retry logic will be invoked here, if this is NOT the first retry
99
+ // (to assist in genuine cases of unknown host) which seems better than outright failure
100
+ cause = new IOException ("UnknownHostException exception: " + e .getMessage ());
101
+ retry = (executionCount > 0 ) && retryHandler .retryRequest (cause , ++executionCount , context );
102
+ } catch (IOException e ) {
103
+ cause = e ;
104
+ retry = retryHandler .retryRequest (cause , ++executionCount , context );
105
+ } catch (NullPointerException e ) {
106
+ // there's a bug in HttpClient 4.0.x that on some occasions causes
107
+ // DefaultRequestExecutor to throw an NPE, see
108
+ // http://code.google.com/p/android/issues/detail?id=5255
109
+ cause = new IOException ("NPE in HttpClient: " + e .getMessage ());
110
+ retry = retryHandler .retryRequest (cause , ++executionCount , context );
112
111
}
113
- return ;
114
- }catch (SocketTimeoutException e ){
115
- if (responseHandler != null ) {
116
- responseHandler .sendFailureMessage (e , "socket time out" );
112
+ if (retry && (responseHandler != null )) {
113
+ responseHandler .sendRetryMessage ();
117
114
}
118
- return ;
119
- } catch (IOException e ) {
120
- cause = e ;
121
- retry = retryHandler .retryRequest (cause , ++executionCount , context );
122
- } catch (NullPointerException e ) {
123
- // there's a bug in HttpClient 4.0.x that on some occasions causes
124
- // DefaultRequestExecutor to throw an NPE, see
125
- // http://code.google.com/p/android/issues/detail?id=5255
126
- cause = new IOException ("NPE in HttpClient" + e .getMessage ());
127
- retry = retryHandler .retryRequest (cause , ++executionCount , context );
128
115
}
116
+ } catch (Exception e ) {
117
+ // catch anything else to ensure failure message is propagated
118
+ cause = new IOException ("Unhandled exception: " + e .getMessage ());
129
119
}
130
-
131
- // no retries left, crap out with exception
132
- ConnectException ex = new ConnectException ();
133
- ex .initCause (cause );
134
- throw ex ;
120
+
121
+ // cleaned up to throw IOException
122
+ throw (cause );
135
123
}
136
124
}
0 commit comments