From 4b4174590b62325617459f75384f49026f0e041c Mon Sep 17 00:00:00 2001 From: Martin Ndegwa Date: Tue, 24 Sep 2024 12:09:20 +0300 Subject: [PATCH] Add a SyncJobStatus result callback amid Sync retries --- .../android/fhir/sync/FhirSyncWorker.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/engine/src/main/java/com/google/android/fhir/sync/FhirSyncWorker.kt b/engine/src/main/java/com/google/android/fhir/sync/FhirSyncWorker.kt index afb43458be..d37bee39ee 100644 --- a/engine/src/main/java/com/google/android/fhir/sync/FhirSyncWorker.kt +++ b/engine/src/main/java/com/google/android/fhir/sync/FhirSyncWorker.kt @@ -21,6 +21,7 @@ import androidx.work.CoroutineWorker import androidx.work.Data import androidx.work.WorkerParameters import androidx.work.workDataOf +import ca.uhn.fhir.context.FhirContext import com.google.android.fhir.FhirEngine import com.google.android.fhir.FhirEngineProvider import com.google.android.fhir.OffsetDateTimeTypeAdapter @@ -32,11 +33,15 @@ import com.google.android.fhir.sync.upload.request.UploadRequestGeneratorFactory import com.google.gson.ExclusionStrategy import com.google.gson.FieldAttributes import com.google.gson.GsonBuilder +import java.nio.charset.StandardCharsets import java.time.OffsetDateTime import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel import kotlinx.coroutines.launch +import org.apache.commons.io.IOUtils +import org.hl7.fhir.r4.model.OperationOutcome +import retrofit2.HttpException import timber.log.Timber /** @@ -135,6 +140,8 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter } val result = synchronizer.synchronize() + if (result is SyncJobStatus.Failed) onFailedSyncJobResult(result) + val output = buildWorkData(result) // await/join is needed to collect states completely @@ -155,6 +162,34 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter } } + open fun onFailedSyncJobResult(failedSyncJobStatus: SyncJobStatus.Failed) { + try { + val jsonParser = FhirContext.forR4().newJsonParser() + val exceptions = (failedSyncJobStatus).exceptions + + exceptions.forEach { resourceSyncException -> + val operationOutcome = + jsonParser.parseResource( + IOUtils.toString( + (resourceSyncException.exception as HttpException) + .response() + ?.errorBody() + ?.byteStream(), + StandardCharsets.UTF_8, + ), + ) as OperationOutcome + + operationOutcome.issue.forEach { operationOutcomeIssueComponent -> + Timber.e( + "SERVER ${operationOutcomeIssueComponent.severity} - HTTP ${resourceSyncException.exception.code()} | Code - ${operationOutcomeIssueComponent.code} | Diagnostics - ${operationOutcomeIssueComponent.diagnostics}", + ) + } + } + } catch (e: Exception) { + Timber.e(e) + } + } + private fun buildWorkData(state: SyncJobStatus): Data { return workDataOf( // send serialized state and type so that consumer can convert it back