diff --git a/frontend/src/app/components/medical-sources-connected/medical-sources-connected.component.ts b/frontend/src/app/components/medical-sources-connected/medical-sources-connected.component.ts index 33cf601e..4508b58d 100644 --- a/frontend/src/app/components/medical-sources-connected/medical-sources-connected.component.ts +++ b/frontend/src/app/components/medical-sources-connected/medical-sources-connected.component.ts @@ -14,6 +14,7 @@ import {EventBusService} from '../../services/event-bus.service'; import {SourceState} from '../../models/fasten/source-state'; import {PatientAccessBrand} from '../../models/patient-access-brands'; import {environment} from '../../../environments/environment'; +import {BackgroundJobSyncData} from '../../models/fasten/background-job'; @Component({ selector: 'app-medical-sources-connected', @@ -232,10 +233,33 @@ export class MedicalSourcesConnectedComponent implements OnInit { const toastNotification = new ToastNotification() toastNotification.type = ToastType.Error - toastNotification.message = `An error occurred while accessing external data source: '${this.extractErrorFromResponse(err)}'` + toastNotification.message = `An error occurred while initializing external data source connection: '${this.extractErrorFromResponse(err)}'` toastNotification.autohide = false this.toastService.show(toastNotification) console.error(err) + + let errData = new BackgroundJobSyncData() + errData.source_id = expectedSourceStateInfo.reconnect_source_id + errData.brand_id = expectedSourceStateInfo.brand_id + errData.checkpoint_data = { + //don't copy confidential data to the error data + state: expectedSourceStateInfo.state, + endpoint_id: expectedSourceStateInfo.endpoint_id, + portal_id: expectedSourceStateInfo.portal_id, + brand_id: expectedSourceStateInfo.brand_id, + reconnect_source_id: expectedSourceStateInfo.reconnect_source_id, + code_challenge_method: expectedSourceStateInfo.code_challenge_method, + redirect_uri: expectedSourceStateInfo.redirect_uri, + } + errData.error_data = { + summary: toastNotification.message, + error: JSON.stringify(err), + stack: err.stack + } + + //attempt to persist this error to the background job table. ignore any errors that occur during this process. + this.fastenApi.createBackgroundJobError(errData).subscribe(console.log) + }) } diff --git a/frontend/src/app/models/fasten/background-job.ts b/frontend/src/app/models/fasten/background-job.ts index 5b41a074..d0557cec 100644 --- a/frontend/src/app/models/fasten/background-job.ts +++ b/frontend/src/app/models/fasten/background-job.ts @@ -9,3 +9,11 @@ export class BackgroundJob { retries: number schedule?: string } + +export class BackgroundJobSyncData { + source_id?: string + brand_id: string + checkpoint_data?: {[key:string]:string} + error_data?: {[key:string]:string} + +} diff --git a/frontend/src/app/services/fasten-api.service.ts b/frontend/src/app/services/fasten-api.service.ts index 9a02e2c6..ed293be5 100644 --- a/frontend/src/app/services/fasten-api.service.ts +++ b/frontend/src/app/services/fasten-api.service.ts @@ -22,7 +22,7 @@ import {DashboardConfig} from '../models/widget/dashboard-config'; import {DashboardWidgetQuery} from '../models/widget/dashboard-widget-query'; import {ResourceGraphResponse} from '../models/fasten/resource-graph-response'; import { fetchEventSource } from '@microsoft/fetch-event-source'; -import {BackgroundJob} from '../models/fasten/background-job'; +import {BackgroundJob, BackgroundJobSyncData} from '../models/fasten/background-job'; import {SupportRequest} from '../models/fasten/support-request'; import { List @@ -335,6 +335,17 @@ export class FastenApiService { ); } + //this method will persist client side errors in the database for later review & easier debugging. Primarily used for source/provider connection errors + createBackgroundJobError(errorData: BackgroundJobSyncData){ + return this._httpClient.post(`${GetEndpointAbsolutePath(globalThis.location, environment.fasten_api_endpoint_base)}/secure/jobs/error`, errorData) + .pipe( + map((response: ResponseWrapper) => { + console.log("RESPONSE", response) + return response.data + }) + ); + } + supportRequest(request: SupportRequest): Observable { return this._httpClient.post(`${GetEndpointAbsolutePath(globalThis.location, environment.fasten_api_endpoint_base)}/support/request`, request)