11package com .cloudinary .android ;
22
33import android .content .Context ;
4+ import android .support .annotation .NonNull ;
45
56import com .cloudinary .Cloudinary ;
67import com .cloudinary .ProgressCallback ;
2021
2122import java .io .IOException ;
2223import java .io .InterruptedIOException ;
24+ import java .util .Locale ;
2325import java .util .Map ;
2426import java .util .concurrent .atomic .AtomicInteger ;
2527
3436 */
3537class DefaultRequestProcessor implements RequestProcessor {
3638 private static final String TAG = "DefaultRequestProcessor" ;
39+ public static final String ERROR_COUNT_PARAM = "errorCount" ;
3740 private final CallbackDispatcher callbackDispatcher ;
3841 private AtomicInteger runningJobs = new AtomicInteger (0 );
3942
@@ -51,15 +54,10 @@ public UploadStatus processRequest(Context context, RequestParams params) {
5154 final String uri = params .getString ("uri" , null );
5255 final String optionsAsString = params .getString ("options" , null );
5356 final int maxErrorRetries = params .getInt ("maxErrorRetries" , MediaManager .get ().getGlobalUploadPolicy ().getMaxErrorRetries ());
54- final int errorCount = params .getInt ("errorCount" , 0 );
57+ final int errorCount = params .getInt (ERROR_COUNT_PARAM , 0 );
5558
5659 Logger .i (TAG , String .format ("Processing Request %s." , requestId ));
5760
58- if (errorCount > maxErrorRetries ) {
59- Logger .d (TAG , String .format ("Failing request %s, too many errors: %d, max: %d" , requestId , errorCount , maxErrorRetries ));
60- return FAILURE ;
61- }
62-
6361 callbackDispatcher .dispatchStart (requestId );
6462 callbackDispatcher .wakeListenerServiceWithRequestStart (context , requestId );
6563
@@ -78,63 +76,79 @@ public UploadStatus processRequest(Context context, RequestParams params) {
7876
7977 ErrorInfo error = null ;
8078
81- if (optionsLoadedSuccessfully ) {
82- if (StringUtils .isNotBlank (uri )) {
83- Payload payload = PayloadFactory .fromUri (uri );
84- if (payload != null ) {
85- try {
86- runningJobs .incrementAndGet ();
87- resultData = doProcess (requestId , appContext , options , params , payload );
88- requestResultStatus = SUCCESS ;
89- } catch (FileNotFoundException e ) {
90- Logger .e (TAG , String .format ("FileNotFoundException for request %s." , requestId ), e );
91- requestResultStatus = FAILURE ;
92- error = new ErrorInfo (ErrorInfo .FILE_DOES_NOT_EXIST , e .getMessage ());
93- } catch (LocalUriNotFoundException e ) {
94- Logger .e (TAG , String .format ("LocalUriNotFoundException for request %s." , requestId ), e );
95- requestResultStatus = FAILURE ;
96- error = new ErrorInfo (ErrorInfo .URI_DOES_NOT_EXIST , e .getMessage ());
97- } catch (ResourceNotFoundException e ) {
98- Logger .e (TAG , String .format ("ResourceNotFoundException for request %s." , requestId ), e );
99- error = new ErrorInfo (ErrorInfo .RESOURCE_DOES_NOT_EXIST , e .getMessage ());
100- requestResultStatus = FAILURE ;
101- } catch (EmptyByteArrayException e ) {
102- Logger .e (TAG , String .format ("EmptyByteArrayException for request %s." , requestId ), e );
103- requestResultStatus = FAILURE ;
104- error = new ErrorInfo (ErrorInfo .BYTE_ARRAY_PAYLOAD_EMPTY , e .getMessage ());
105- } catch (InterruptedIOException e ) {
106- Logger .e (TAG , String .format ("InterruptedIO exception for request %s." , requestId ), e );
107- error = new ErrorInfo (ErrorInfo .REQUEST_CANCELLED , "Request cancelled." );
108- requestResultStatus = FAILURE ;
109- } catch (ErrorRetrievingSignatureException e ) {
110- Logger .e (TAG , String .format ("Error retrieving signature for request %s." , requestId ), e );
111- requestResultStatus = FAILURE ;
112- error = new ErrorInfo (ErrorInfo .SIGNATURE_FAILURE , e .getMessage ());
113- } catch (IOException e ) {
114- Logger .e (TAG , String .format ("IOException for request %s." , requestId ), e );
115- error = new ErrorInfo (ErrorInfo .NETWORK_ERROR , e .getMessage ());
116- requestResultStatus = RESCHEDULE ;
117- } catch (Exception e ) {
118- Logger .e (TAG , String .format ("Unexpected exception for request %s." , requestId ), e );
119- error = new ErrorInfo (ErrorInfo .UNKNOWN_ERROR , e .getMessage ());
79+ if (errorCount < maxErrorRetries ) {
80+ if (optionsLoadedSuccessfully ) {
81+ if (StringUtils .isNotBlank (uri )) {
82+ Payload payload = PayloadFactory .fromUri (uri );
83+ if (payload != null ) {
84+ try {
85+ runningJobs .incrementAndGet ();
86+ resultData = doProcess (requestId , appContext , options , params , payload );
87+ requestResultStatus = SUCCESS ;
88+ } catch (FileNotFoundException e ) {
89+ Logger .e (TAG , String .format ("FileNotFoundException for request %s." , requestId ), e );
90+ requestResultStatus = FAILURE ;
91+ error = new ErrorInfo (ErrorInfo .FILE_DOES_NOT_EXIST , e .getMessage ());
92+ } catch (LocalUriNotFoundException e ) {
93+ Logger .e (TAG , String .format ("LocalUriNotFoundException for request %s." , requestId ), e );
94+ requestResultStatus = FAILURE ;
95+ error = new ErrorInfo (ErrorInfo .URI_DOES_NOT_EXIST , e .getMessage ());
96+ } catch (ResourceNotFoundException e ) {
97+ Logger .e (TAG , String .format ("ResourceNotFoundException for request %s." , requestId ), e );
98+ error = new ErrorInfo (ErrorInfo .RESOURCE_DOES_NOT_EXIST , e .getMessage ());
99+ requestResultStatus = FAILURE ;
100+ } catch (EmptyByteArrayException e ) {
101+ Logger .e (TAG , String .format ("EmptyByteArrayException for request %s." , requestId ), e );
102+ requestResultStatus = FAILURE ;
103+ error = new ErrorInfo (ErrorInfo .BYTE_ARRAY_PAYLOAD_EMPTY , e .getMessage ());
104+ } catch (InterruptedIOException e ) {
105+ Logger .e (TAG , String .format ("InterruptedIO exception for request %s." , requestId ), e );
106+ error = new ErrorInfo (ErrorInfo .REQUEST_CANCELLED , "Request cancelled." );
107+ requestResultStatus = FAILURE ;
108+ } catch (ErrorRetrievingSignatureException e ) {
109+ Logger .e (TAG , String .format ("Error retrieving signature for request %s." , requestId ), e );
110+ requestResultStatus = FAILURE ;
111+ error = new ErrorInfo (ErrorInfo .SIGNATURE_FAILURE , e .getMessage ());
112+ } catch (IOException e ) {
113+ Logger .e (TAG , String .format ("IOException for request %s." , requestId ), e );
114+
115+ if (errorCount >= maxErrorRetries ) {
116+ // failure
117+ error = getMaxRetryError (errorCount );
118+ requestResultStatus = FAILURE ;
119+ } else {
120+ // one up error count and reschedule
121+ params .putInt (ERROR_COUNT_PARAM , errorCount + 1 );
122+ error = new ErrorInfo (ErrorInfo .NETWORK_ERROR , e .getMessage ());
123+ requestResultStatus = RESCHEDULE ;
124+ }
125+ } catch (Exception e ) {
126+ Logger .e (TAG , String .format ("Unexpected exception for request %s." , requestId ), e );
127+ error = new ErrorInfo (ErrorInfo .UNKNOWN_ERROR , e .getMessage ());
128+ requestResultStatus = FAILURE ;
129+ } finally {
130+ runningJobs .decrementAndGet ();
131+ }
132+ } else {
133+ Logger .d (TAG , String .format ("Failing request %s, payload cannot be loaded." , requestId ));
134+ error = new ErrorInfo (ErrorInfo .PAYLOAD_LOAD_FAILURE , "Request payload could not be loaded." );
120135 requestResultStatus = FAILURE ;
121- } finally {
122- runningJobs .decrementAndGet ();
123136 }
124137 } else {
125- Logger .d (TAG , String .format ("Failing request %s, payload cannot be loaded." , requestId ));
126- error = new ErrorInfo (ErrorInfo .PAYLOAD_LOAD_FAILURE , "Request payload could not be loaded." );
127138 requestResultStatus = FAILURE ;
139+ error = new ErrorInfo (ErrorInfo .PAYLOAD_EMPTY , "Request payload is empty." );
140+ Logger .d (TAG , String .format ("Failing request %s, Uri is empty." , requestId ));
128141 }
129142 } else {
130143 requestResultStatus = FAILURE ;
131- error = new ErrorInfo (ErrorInfo .PAYLOAD_EMPTY , "Request payload is empty ." );
132- Logger .d (TAG , String .format ("Failing request %s, Uri is empty ." , requestId ));
144+ error = new ErrorInfo (ErrorInfo .OPTIONS_FAILURE , "Options could not be loaded ." );
145+ Logger .d (TAG , String .format ("Failing request %s, cannot load options ." , requestId ));
133146 }
134147 } else {
148+ // safety - this should not really happen - the last error should already trigger
149+ // as failure and should not be rescheduled
150+ error = getMaxRetryError (errorCount );
135151 requestResultStatus = FAILURE ;
136- error = new ErrorInfo (ErrorInfo .OPTIONS_FAILURE , "Options could not be loaded." );
137- Logger .d (TAG , String .format ("Failing request %s, cannot load options." , requestId ));
138152 }
139153
140154 if (requestResultStatus .isFinal ()) {
@@ -147,7 +161,6 @@ public UploadStatus processRequest(Context context, RequestParams params) {
147161 // wake up the listener (this is not needed for reschedules since if the listener is down no point in reschedule notification.
148162 // we'll wake them up once the request is actually finished.
149163 callbackDispatcher .wakeListenerServiceWithRequestFinished (context , requestId , requestResultStatus );
150-
151164 } else {
152165 callbackDispatcher .dispatchReschedule (context , requestId , error );
153166 }
@@ -157,7 +170,19 @@ public UploadStatus processRequest(Context context, RequestParams params) {
157170 return requestResultStatus ;
158171 }
159172
160- private Map doProcess (final String requestId , Context appContext , Map <String , Object > options , RequestParams params , Payload payload ) throws PayloadNotFoundException , IOException , ErrorRetrievingSignatureException {
173+ @ NonNull
174+ private ErrorInfo getMaxRetryError (int errorCount ) {
175+ ErrorInfo error ;
176+ String message = String .format (Locale .getDefault (),
177+ "Request reached max retries allowed (%d)." ,
178+ errorCount );
179+ error = new ErrorInfo (ErrorInfo .TOO_MANY_ERRORS , message );
180+ return error ;
181+ }
182+
183+ private Map doProcess (final String requestId , Context
184+ appContext , Map <String , Object > options , RequestParams params , Payload payload ) throws
185+ PayloadNotFoundException , IOException , ErrorRetrievingSignatureException {
161186 Logger .d (TAG , String .format ("Starting upload for request %s" , requestId ));
162187 Object preparedPayload = payload .prepare (appContext );
163188 final long actualTotalBytes = payload .getLength (appContext );
0 commit comments