From f8f72edeb9255ac7aa5b85d5aa41be4cc8718b79 Mon Sep 17 00:00:00 2001 From: Wojciech Duda <69160975+wojd0@users.noreply.github.com> Date: Wed, 5 Mar 2025 12:53:04 +0100 Subject: [PATCH] AAE-32493 Add error handling for loading task (#10692) * AAE-32493 Add error handling for loading task [ci:force] * AAE-32493 Improve units * AAE-32493 forkJoin observables together * AAE-32493 Remove duplicate loading cancel * AAE-32493 Complete task subscription on error --- .../user-task-cloud.component.spec.ts | 16 +++++++++-- .../user-task-cloud.component.ts | 28 +++++++++++++------ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.spec.ts index 8c07567a8d..8b1f86e88c 100644 --- a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.spec.ts @@ -33,7 +33,7 @@ import { MatButtonHarness } from '@angular/material/button/testing'; import { MatCardHarness } from '@angular/material/card/testing'; import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing'; import { ProcessServiceCloudTestingModule } from 'lib/process-services-cloud/src/lib/testing/process-service-cloud.testing.module'; -import { of } from 'rxjs'; +import { of, throwError } from 'rxjs'; import { IdentityUserService } from '../../../../people/services/identity-user.service'; import { UserTaskCloudComponent } from './user-task-cloud.component'; @@ -60,6 +60,7 @@ describe('UserTaskCloudComponent', () => { let getCurrentUserSpy: jasmine.Spy; let loader: HarnessLoader; let identityUserService: IdentityUserService; + let errorEmitSpy: jasmine.Spy; beforeEach(() => { TestBed.configureTestingModule({ @@ -67,6 +68,7 @@ describe('UserTaskCloudComponent', () => { }); fixture = TestBed.createComponent(UserTaskCloudComponent); component = fixture.componentInstance; + errorEmitSpy = spyOn(component.error, 'emit'); loader = TestbedHarnessEnvironment.loader(fixture); taskCloudService = TestBed.inject(TaskCloudService); identityUserService = TestBed.inject(IdentityUserService); @@ -288,6 +290,15 @@ describe('UserTaskCloudComponent', () => { expect(getTaskSpy).not.toHaveBeenCalled(); }); + + it('should emit error when getTaskById fails', async () => { + getTaskSpy.and.returnValue(throwError(() => 'getTaskyById error')); + component.taskId = 'task1'; + component.ngOnChanges({ appName: new SimpleChange(null, 'app1', false) }); + await fixture.whenStable(); + + expect(errorEmitSpy).toHaveBeenCalledWith('getTaskyById error'); + }); }); describe('Events', () => { @@ -344,12 +355,11 @@ describe('UserTaskCloudComponent', () => { }); it('should emit error when error occurs', async () => { - spyOn(component.error, 'emit').and.stub(); component.onError({}); fixture.detectChanges(); await fixture.whenStable(); - expect(component.error.emit).toHaveBeenCalled(); + expect(errorEmitSpy).toHaveBeenCalled(); }); it('should reload when task is completed', async () => { diff --git a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.ts index f7aa887117..6528d59945 100644 --- a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/user-task-cloud.component.ts @@ -30,6 +30,7 @@ import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { TaskScreenCloudComponent } from '../../../../screen/components/screen-cloud/screen-cloud.component'; import { CompleteTaskDirective } from './complete-task/complete-task.directive'; +import { catchError, EMPTY, forkJoin } from 'rxjs'; const TaskTypes = { Form: 'form', @@ -251,18 +252,29 @@ export class UserTaskCloudComponent implements OnInit, OnChanges { private loadTask(): void { this.loading = true; - this.taskCloudService - .getTaskById(this.appName, this.taskId) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe((details) => { - this.taskDetails = details; + const tasks$ = this.taskCloudService.getTaskById(this.appName, this.taskId); + const candidateUsers$ = this.taskCloudService.getCandidateUsers(this.appName, this.taskId); + const candidateGroups$ = this.taskCloudService.getCandidateGroups(this.appName, this.taskId); + forkJoin({ + tasks: tasks$, + candidateUsers: candidateUsers$, + candidateGroups: candidateGroups$ + }) + .pipe( + takeUntilDestroyed(this.destroyRef), + catchError((error) => { + this.onError(error); + return EMPTY; + }) + ) + .subscribe(({ tasks, candidateGroups, candidateUsers }) => { + this.taskDetails = tasks; this.getTaskType(); + this.candidateUsers = candidateUsers; + this.candidateGroups = candidateGroups; this.loading = false; this.onTaskLoaded.emit(this.taskDetails); }); - - this.taskCloudService.getCandidateUsers(this.appName, this.taskId).subscribe((users) => (this.candidateUsers = users || [])); - this.taskCloudService.getCandidateGroups(this.appName, this.taskId).subscribe((groups) => (this.candidateGroups = groups || [])); } public switchToDisplayMode(newDisplayMode?: string): void {