Skip to content

Commit d1cf331

Browse files
committed
skip server error when fetching diagn.serv.items
1 parent e530891 commit d1cf331

3 files changed

Lines changed: 181 additions & 5 deletions

File tree

claimManagement/src/main/java/org/openimis/imisclaims/MainActivity.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,18 @@ public void run() {
688688

689689
runOnUiThread(() -> {
690690
progressDialog.dismiss();
691-
if (officerCode != null) {
691+
if (!fetchDiagnosesServicesItems.getSkippedMedicationPages().isEmpty()) {
692+
final String errorLogMessage = "Master data synced with partial medications.\nSkipped pages: "
693+
+ fetchDiagnosesServicesItems.getSkippedMedicationPages();
694+
showDialog(
695+
errorLogMessage,
696+
(dialog, which) -> {
697+
if (officerCode != null) {
698+
DownLoadServicesItemsPriceList(officerCode);
699+
}
700+
}
701+
);
702+
} else if (officerCode != null) {
692703
DownLoadServicesItemsPriceList(officerCode);
693704
}
694705
});

claimManagement/src/main/java/org/openimis/imisclaims/network/util/PaginatedResponseUtils.java

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
import androidx.annotation.Nullable;
55
import androidx.annotation.WorkerThread;
66

7+
import org.openimis.imisclaims.network.exception.HttpException;
78
import org.openimis.imisclaims.network.request.BaseFHIRGetPaginatedRequest;
89
import org.openimis.imisclaims.network.response.PaginatedResponse;
10+
import org.openimis.imisclaims.tools.Log;
911

1012
import java.util.ArrayList;
1113
import java.util.Collection;
14+
import java.util.Collections;
1215
import java.util.List;
1316

1417
public class PaginatedResponseUtils {
18+
private static final String LOG_TAG = "FHIR_SYNC_TOLERANCE";
1519

1620
private PaginatedResponseUtils() {
1721
throw new IllegalAccessError("This constructor is private");
@@ -50,10 +54,154 @@ public static <T, U> List<U> downloadAll(
5054
return list;
5155
}
5256

57+
@NonNull
58+
@WorkerThread
59+
public static <T, U> DownloadResult<U> downloadAllSkipFailedPages(
60+
@NonNull String endpoint,
61+
@NonNull RequestExecutor<T> executor,
62+
@Nullable Mapper.Transformer<T, U> transformer,
63+
int maxPages,
64+
int maxConsecutiveFailures
65+
) throws Exception {
66+
int page = 0;
67+
int consecutiveFailures = 0;
68+
boolean hasMore = true;
69+
boolean hasSkippedPages = false;
70+
List<U> list = new ArrayList<>();
71+
List<Integer> skippedPages = new ArrayList<>();
72+
List<Integer> recoveredPages = new ArrayList<>();
73+
Mapper<T, U> mapper = transformer != null ? new Mapper<>(transformer) : null;
74+
75+
while (hasMore && page < maxPages) {
76+
final int displayPage = page + 1;
77+
try {
78+
PaginatedResponse<T> response = executor.download(page);
79+
if (mapper != null) {
80+
list.addAll(mapper.map(response.getValue()));
81+
} else {
82+
list.addAll((Collection<? extends U>) response.getValue());
83+
}
84+
hasMore = response.hasMore();
85+
consecutiveFailures = 0;
86+
if (hasSkippedPages) {
87+
recoveredPages.add(displayPage);
88+
}
89+
} catch (Exception exception) {
90+
skippedPages.add(displayPage);
91+
hasSkippedPages = true;
92+
consecutiveFailures++;
93+
logSkippedPage(endpoint, displayPage, exception);
94+
if (consecutiveFailures >= maxConsecutiveFailures) {
95+
Log.w(
96+
LOG_TAG,
97+
String.format(
98+
"endpoint=%s action=stop reason=maxConsecutiveFailures reached skippedPages=%s",
99+
endpoint,
100+
skippedPages
101+
)
102+
);
103+
break;
104+
}
105+
}
106+
page++;
107+
}
108+
109+
if (page >= maxPages && hasMore) {
110+
Log.w(
111+
LOG_TAG,
112+
String.format(
113+
"endpoint=%s action=stop reason=maxPages reached maxPages=%s skippedPages=%s",
114+
endpoint,
115+
maxPages,
116+
skippedPages
117+
)
118+
);
119+
}
120+
121+
Log.i(
122+
LOG_TAG,
123+
String.format(
124+
"endpoint=%s summary skippedPages=%s recoveredPages=%s totalItems=%s",
125+
endpoint,
126+
skippedPages,
127+
recoveredPages,
128+
list.size()
129+
)
130+
);
131+
return new DownloadResult<>(list, skippedPages, recoveredPages);
132+
}
133+
134+
private static void logSkippedPage(@NonNull String endpoint, int page, @NonNull Exception exception) {
135+
String errorType = exception.getClass().getSimpleName();
136+
if (exception instanceof HttpException) {
137+
HttpException httpException = (HttpException) exception;
138+
Log.w(
139+
LOG_TAG,
140+
String.format(
141+
"endpoint=%s page=%s action=skip errorType=%s code=%s message=%s",
142+
endpoint,
143+
page,
144+
errorType,
145+
httpException.getCode(),
146+
exception.getMessage()
147+
)
148+
);
149+
} else {
150+
Log.w(
151+
LOG_TAG,
152+
String.format(
153+
"endpoint=%s page=%s action=skip errorType=%s message=%s",
154+
endpoint,
155+
page,
156+
errorType,
157+
exception.getMessage()
158+
)
159+
);
160+
}
161+
}
162+
53163
public interface RequestExecutor<T> {
54164

55165
@NonNull
56166
@WorkerThread
57167
PaginatedResponse<T> download(int page) throws Exception;
58168
}
169+
170+
public static class DownloadResult<U> {
171+
@NonNull
172+
private final List<U> items;
173+
@NonNull
174+
private final List<Integer> skippedPages;
175+
@NonNull
176+
private final List<Integer> recoveredPages;
177+
178+
public DownloadResult(
179+
@NonNull List<U> items,
180+
@NonNull List<Integer> skippedPages,
181+
@NonNull List<Integer> recoveredPages
182+
) {
183+
this.items = items;
184+
this.skippedPages = skippedPages;
185+
this.recoveredPages = recoveredPages;
186+
}
187+
188+
@NonNull
189+
public List<U> getItems() {
190+
return items;
191+
}
192+
193+
@NonNull
194+
public List<Integer> getSkippedPages() {
195+
return Collections.unmodifiableList(skippedPages);
196+
}
197+
198+
@NonNull
199+
public List<Integer> getRecoveredPages() {
200+
return Collections.unmodifiableList(recoveredPages);
201+
}
202+
203+
public boolean hasSkippedPages() {
204+
return !skippedPages.isEmpty();
205+
}
206+
}
59207
}

claimManagement/src/main/java/org/openimis/imisclaims/usecase/FetchDiagnosesServicesItems.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
import org.openimis.imisclaims.util.DateUtils;
2020

2121
import java.util.Date;
22+
import java.util.List;
2223

2324
public class FetchDiagnosesServicesItems {
25+
private static final int MAX_PAGES = 1000;
26+
private static final int MAX_CONSECUTIVE_FAILURES = 3;
2427

2528
@NonNull
2629
private final GetActivityDefinitionsRequest getActivityDefinitionsRequest;
2730
@NonNull
2831
private final GetDiagnosesRequest getDiagnosesRequest;
2932
@NonNull
3033
private final GetMedicationsRequest getMedicationsRequest;
34+
@NonNull
35+
private List<Integer> skippedMedicationPages = java.util.Collections.emptyList();
3136

3237
public FetchDiagnosesServicesItems() {
3338
this(
@@ -50,6 +55,16 @@ public FetchDiagnosesServicesItems(
5055
@NonNull
5156
@WorkerThread
5257
public DiagnosesServicesMedications execute() throws Exception {
58+
PaginatedResponseUtils.DownloadResult<Medication> medicationDownloadResult =
59+
PaginatedResponseUtils.downloadAllSkipFailedPages(
60+
"Medication",
61+
getMedicationsRequest::get,
62+
this::toMedication,
63+
MAX_PAGES,
64+
MAX_CONSECUTIVE_FAILURES
65+
);
66+
skippedMedicationPages = medicationDownloadResult.getSkippedPages();
67+
5368
// previous code was passing sometimes a `last_updated_date` but it was either empty or
5469
// `new Date(0)`. I'm still returning the last updated date in case it's one day used
5570
// again.¯\_(ツ)_/¯
@@ -60,13 +75,15 @@ public DiagnosesServicesMedications execute() throws Exception {
6075
getActivityDefinitionsRequest::get,
6176
this::toService
6277
),
63-
/* medications = */ PaginatedResponseUtils.downloadAll(
64-
getMedicationsRequest::get,
65-
this::toMedication
66-
)
78+
/* medications = */ medicationDownloadResult.getItems()
6779
);
6880
}
6981

82+
@NonNull
83+
public List<Integer> getSkippedMedicationPages() {
84+
return skippedMedicationPages;
85+
}
86+
7087
@NonNull
7188
private Diagnosis toDiagnosis(@NonNull DiagnosisDto dto) {
7289
return new Diagnosis(

0 commit comments

Comments
 (0)