From 11b70b9337c688dae5b1bcfd788a90f9029e6353 Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Tue, 4 Aug 2026 08:29:22 +0200 Subject: [PATCH] feat: add error handling to CashboxExportDialog --- .../cashbox-export-dialog.spec.ts | 24 ++++++++++++++++++- .../cashbox-export-dialog.ts | 19 +++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.spec.ts b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.spec.ts index 05dcdb1..d2ed942 100644 --- a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.spec.ts +++ b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { of } from 'rxjs'; +import { of, throwError } from 'rxjs'; import { CashboxExportApi } from '../../../../core/team/cashbox-export-api'; import { FileDownloadService } from '../../../../shared/file-download/file-download.service'; import { CashboxExportDialog } from './cashbox-export-dialog'; @@ -46,4 +46,26 @@ describe('CashboxExportDialog', () => { expect(save).toHaveBeenCalledWith(expect.any(Blob), 'kassenbuch_2026-08-01_2026-08-31.csv'); expect(dialogRef.close).toHaveBeenCalled(); }); + + it('displays error message and does not close dialog on export failure', () => { + exportCashbox = vi.fn(() => throwError(() => new Error('network error'))); + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + imports: [CashboxExportDialog], + providers: [ + { provide: MAT_DIALOG_DATA, useValue: { teamId: 5 } }, + { provide: MatDialogRef, useValue: dialogRef }, + { provide: CashboxExportApi, useValue: { exportCashbox } }, + { provide: FileDownloadService, useValue: { save } }, + ], + }); + fixture = TestBed.createComponent(CashboxExportDialog); + fixture.detectChanges(); + + fixture.componentInstance['form'].setValue({ from: '2026-08-01', to: '2026-08-31', format: 'csv' }); + fixture.componentInstance['download'](); + + expect(dialogRef.close).not.toHaveBeenCalled(); + expect(fixture.componentInstance['downloadError']()).toBe('Export konnte nicht heruntergeladen werden.'); + }); }); diff --git a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.ts b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.ts index 2bc86c2..0788ec5 100644 --- a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.ts +++ b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox-export-dialog/cashbox-export-dialog.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, signal } from '@angular/core'; import { FormBuilder, ReactiveFormsModule, ValidationErrors, ValidatorFn, Validators } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; @@ -29,6 +29,9 @@ const rangeValid: ValidatorFn = (group): ValidationErrors | null => {

Kassenbuch exportieren

+ @if (downloadError()) { +

{{ downloadError() }}

+ } Von @@ -59,6 +62,8 @@ export class CashboxExportDialog { private readonly api = inject(CashboxExportApi); private readonly fileDownload = inject(FileDownloadService); + protected readonly downloadError = signal(null); + protected readonly form = this.formBuilder.nonNullable.group( { from: ['', Validators.required], @@ -70,10 +75,16 @@ export class CashboxExportDialog { protected download(): void { if (this.form.invalid) return; + this.downloadError.set(null); const { from, to, format } = this.form.getRawValue(); - this.api.exportCashbox(this.data.teamId, from, to, format).subscribe((blob) => { - this.fileDownload.save(blob, `kassenbuch_${from}_${to}.${format}`); - this.dialogRef.close(); + this.api.exportCashbox(this.data.teamId, from, to, format).subscribe({ + next: (blob) => { + this.fileDownload.save(blob, `kassenbuch_${from}_${to}.${format}`); + this.dialogRef.close(); + }, + error: () => { + this.downloadError.set('Export konnte nicht heruntergeladen werden.'); + }, }); } }