@@ -21,6 +21,7 @@ import androidx.work.CoroutineWorker
21
21
import androidx.work.Data
22
22
import androidx.work.WorkerParameters
23
23
import androidx.work.workDataOf
24
+ import ca.uhn.fhir.context.FhirContext
24
25
import com.google.android.fhir.FhirEngine
25
26
import com.google.android.fhir.FhirEngineProvider
26
27
import com.google.android.fhir.OffsetDateTimeTypeAdapter
@@ -32,11 +33,15 @@ import com.google.android.fhir.sync.upload.request.UploadRequestGeneratorFactory
32
33
import com.google.gson.ExclusionStrategy
33
34
import com.google.gson.FieldAttributes
34
35
import com.google.gson.GsonBuilder
36
+ import java.nio.charset.StandardCharsets
35
37
import java.time.OffsetDateTime
36
38
import kotlinx.coroutines.CoroutineScope
37
39
import kotlinx.coroutines.Dispatchers
38
40
import kotlinx.coroutines.cancel
39
41
import kotlinx.coroutines.launch
42
+ import org.apache.commons.io.IOUtils
43
+ import org.hl7.fhir.r4.model.OperationOutcome
44
+ import retrofit2.HttpException
40
45
import timber.log.Timber
41
46
42
47
/* *
@@ -135,6 +140,8 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter
135
140
}
136
141
137
142
val result = synchronizer.synchronize()
143
+ if (result is SyncJobStatus .Failed ) onFailedSyncJobResult(result)
144
+
138
145
val output = buildWorkData(result)
139
146
140
147
// await/join is needed to collect states completely
@@ -155,6 +162,34 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter
155
162
}
156
163
}
157
164
165
+ open fun onFailedSyncJobResult (failedSyncJobStatus : SyncJobStatus .Failed ) {
166
+ try {
167
+ val jsonParser = FhirContext .forR4().newJsonParser()
168
+ val exceptions = (failedSyncJobStatus).exceptions
169
+
170
+ exceptions.forEach { resourceSyncException ->
171
+ val operationOutcome =
172
+ jsonParser.parseResource(
173
+ IOUtils .toString(
174
+ (resourceSyncException.exception as HttpException )
175
+ .response()
176
+ ?.errorBody()
177
+ ?.byteStream(),
178
+ StandardCharsets .UTF_8 ,
179
+ ),
180
+ ) as OperationOutcome
181
+
182
+ operationOutcome.issue.forEach { operationOutcomeIssueComponent ->
183
+ Timber .e(
184
+ " SERVER ${operationOutcomeIssueComponent.severity} - HTTP ${resourceSyncException.exception.code()} | Code - ${operationOutcomeIssueComponent.code} | Diagnostics - ${operationOutcomeIssueComponent.diagnostics} " ,
185
+ )
186
+ }
187
+ }
188
+ } catch (e: Exception ) {
189
+ Timber .e(e)
190
+ }
191
+ }
192
+
158
193
private fun buildWorkData (state : SyncJobStatus ): Data {
159
194
return workDataOf(
160
195
// send serialized state and type so that consumer can convert it back
0 commit comments