Skip to content

Commit

Permalink
Merge pull request #873 from europeana/feat/MET-6255-Error-Handling
Browse files Browse the repository at this point in the history
MET-6255 Improve Error Handling
  • Loading branch information
andyjmaclean authored Nov 22, 2024
2 parents 1cb20ea + c72c605 commit 1446a7d
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 46 deletions.
12 changes: 12 additions & 0 deletions projects/sandbox/cypress/e2e/app-network-errors.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ context('Sandbox', () => {
cy.visit('/dataset');
});

const closeErrors = (): void => {
const selCloseErrors = '.close-errors';
cy.get(selCloseErrors).should('have.length', 1);
cy.get(selCloseErrors).click();
cy.get(selCloseErrors).should('not.exist');
};

it('should show an error when the data upload fails', () => {
const code = '404';
cy.get(selectorLinkDatasetForm).click();
Expand All @@ -24,6 +31,7 @@ context('Sandbox', () => {
cy.get(selectorErrors)
.contains(code)
.should('have.length', 1);
closeErrors();
});

it('should show an error when the progress data load fails', () => {
Expand All @@ -33,6 +41,7 @@ context('Sandbox', () => {
cy.get(selectorErrors)
.contains(code)
.should('have.length', 1);
closeErrors();
});

it('should show an error when the (dateset) problem-pattern load fails', () => {
Expand All @@ -43,6 +52,7 @@ context('Sandbox', () => {
cy.get(selectorErrors)
.contains(code)
.should('have.length', 1);
closeErrors();
});

it('should show an error when the record report load fails', () => {
Expand All @@ -54,6 +64,7 @@ context('Sandbox', () => {
cy.get(selectorErrors)
.contains(code)
.should('have.length', 1);
closeErrors();
});

it('should show an error when the (record) problem-pattern load fails', () => {
Expand All @@ -65,6 +76,7 @@ context('Sandbox', () => {
cy.get(selectorErrors)
.contains(code)
.should('have.length', 1);
closeErrors();
});

it('should remember the errors for each step', () => {
Expand Down
7 changes: 6 additions & 1 deletion projects/sandbox/src/app/http-errors/errors.component.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<div *ngIf="error" class="errors">
@if(error) {
<div class="errors">
@if(onClose) {
<a class="close-errors" (click)="onClose()"></a>
}
<div class="heading">
{{ error.statusText }}
</div>
<ul class="error-detail">
<li>{{ error.message }}</li>
</ul>
</div>
}
24 changes: 24 additions & 0 deletions projects/sandbox/src/app/http-errors/errors.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.close-errors {
clear: both;
float: right;
height: 1rem;
position: relative;
top: 2px;
z-index: 1;

&::before,
&::after {
background: red;
content: '';
display: block;
height: 0.175rem;
margin-top: 0.375rem;
transform: rotate(45deg);
width: 1rem;
}

&::after {
margin-top: -0.175rem;
transform: rotate(-45deg);
}
}
6 changes: 3 additions & 3 deletions projects/sandbox/src/app/http-errors/errors.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { NgIf } from '@angular/common';
import { Component, Input } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
selector: 'sb-http-errors',
styleUrls: ['./errors.component.scss'],
templateUrl: './errors.component.html',
standalone: true,
imports: [NgIf]
standalone: true
})
export class HttpErrorsComponent {
@Input() error: HttpErrorResponse | undefined;
@Input() onClose: (() => void) | undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ <h1 class="header-text" *ngIf="currentStepIndex === i">
</li>
</ul>
</ng-container>
<sb-http-errors [error]="sandboxNavConf[currentStepIndex].error"></sb-http-errors>
<sb-http-errors
[error]="sandboxNavConf[currentStepIndex].error"
[onClose]="clearError.bind(this)"
></sb-http-errors>
</div>
</main>
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,11 @@ describe('SandboxNavigatonComponent', () => {
expect(component.sandboxNavConf[confIndex].error).toBeTruthy();
expect(component.progressData).toBeFalsy();
expect(component.formProgress.value.datasetToTrack).toBeTruthy();

component.currentStepIndex = confIndex;
component.clearError();
expect(component.sandboxNavConf[confIndex].error).toBeFalsy();

component.cleanup();
tick(apiSettings.interval);
}));
Expand Down Expand Up @@ -650,6 +655,9 @@ describe('SandboxNavigatonComponent', () => {
expect(component.sandboxNavConf[index].error).toBeTruthy();
expect(component.recordReport).toBeFalsy();

component.clearError();
expect(component.sandboxNavConf[index].error).toBeFalsy();

component.cleanup();
tick(apiSettings.interval);
}));
Expand All @@ -660,6 +668,12 @@ describe('SandboxNavigatonComponent', () => {
component.submitDatasetProblemPatterns();
tick(1);
expect(component.sandboxNavConf[stepIndexProblemsDataset].error).toBeTruthy();

component.clearError();
expect(component.sandboxNavConf[stepIndexProblemsDataset].error).toBeTruthy();
component.currentStepIndex = stepIndexProblemsDataset;
component.clearError();
expect(component.sandboxNavConf[stepIndexProblemsDataset].error).toBeFalsy();
}));

it('should handle problem pattern errors (record)', fakeAsync(() => {
Expand All @@ -669,6 +683,10 @@ describe('SandboxNavigatonComponent', () => {
component.submitRecordProblemPatterns();
tick(1);
expect(component.sandboxNavConf[stepIndexProblemsRecord].error).toBeTruthy();

component.currentStepIndex = stepIndexProblemsRecord;
component.clearError();
expect(component.sandboxNavConf[stepIndexProblemsRecord].error).toBeFalsy();
}));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ export class SandboxNavigatonComponent extends DataPollingComponent implements O
this.resetPageData();
}

/**
* clearError
*
* reset the step error
**/
clearError(): void {
this.sandboxNavConf[this.currentStepIndex].error = undefined;
}

/**
* getNavOrbConfigOuter
*
Expand Down
2 changes: 1 addition & 1 deletion projects/sandbox/src/app/upload/upload.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -180,5 +180,5 @@
<span class="label">Submit</span>
</button>

<sb-http-errors [error]="error"></sb-http-errors>
<sb-http-errors [error]="error" [onClose]="rebuildForm.bind(this)"></sb-http-errors>
</form>
77 changes: 37 additions & 40 deletions projects/sandbox/src/app/upload/upload.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
AbstractControl,
FormBuilder,
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
ValidationErrors,
Expand Down Expand Up @@ -65,10 +66,11 @@ export class UploadComponent extends DataPollingComponent {
modalIdStepSizeInfo = 'id-modal-step-size-info';

error: HttpErrorResponse | undefined;
form: FormGroup;

constructor() {
super();

this.rebuildForm();
this.subs.push(
this.sandbox.getCountries().subscribe((countries: Array<FieldOption>) => {
this.countryList = countries;
Expand All @@ -93,48 +95,43 @@ export class UploadComponent extends DataPollingComponent {
* invokes form reset after clearing file inputs from previous submission
**/
rebuildForm(): void {
this.protocolFields.clearFileValue();
this.xslFileField.clearFileValue();
this.form.reset();
this.form.controls.stepSize.setValue('1');
this.error = undefined;
}

form = this.formBuilder.group({
name: ['', [Validators.required, this.validateDatasetName]],
country: ['', [Validators.required]],
language: ['', [Validators.required]],
uploadProtocol: [ProtocolType.ZIP_UPLOAD, [Validators.required]],
url: ['', [Validators.required]],
stepSize: [
'1',
[
(control: AbstractControl): ValidationErrors | null => {
const value = control.value;
const parsedValue = parseInt(value);
const isNumeric = `${parsedValue}` === value;

if (value) {
if (!isNumeric) {
return { nonNumeric: true };
} else if (parsedValue < 1) {
return { min: true };
this.form = this.formBuilder.group({
name: ['', [Validators.required, this.validateDatasetName]],
country: ['', [Validators.required]],
language: ['', [Validators.required]],
uploadProtocol: [ProtocolType.ZIP_UPLOAD, [Validators.required]],
url: ['', [Validators.required]],
stepSize: [
'1',
[
(control: AbstractControl): ValidationErrors | null => {
const value = control.value;
const parsedValue = parseInt(value);
const isNumeric = `${parsedValue}` === value;

if (value) {
if (!isNumeric) {
return { nonNumeric: true };
} else if (parsedValue < 1) {
return { min: true };
}
} else {
return { required: true };
}
} else {
return { required: true };
return null;
}
return null;
}
]
],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dataset: [(undefined as any) as File, [Validators.required]],
harvestUrl: ['', [Validators.required]],
setSpec: [''],
metadataFormat: [''],
sendXSLT: [false],
xsltFile: ['']
});
]
],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dataset: [(undefined as any) as File, [Validators.required]],
harvestUrl: ['', [Validators.required]],
setSpec: [''],
metadataFormat: [''],
sendXSLT: [false],
xsltFile: ['']
});
}

/**
* protocolIsValid
Expand Down

0 comments on commit 1446a7d

Please sign in to comment.