Add comprehensive error handling to Python and JavaScript files

This commit enhances error handling across the codebase with clear, user-friendly error messages:

Python Files:
- main.py: Added error handling for directory creation and file operations
- read_excel.py: Added error handling for file loading, JSON parsing, and data output
- fill_plan_dates.py: Added input validation and error handling for file operations and date calculations
- calculate.py: Improved error handling in load_holidays() and process_file() with detailed warnings for invalid data
- build_template.py: Added error handling for directory creation, workbook creation, and file saving

JavaScript Files:
- storage.js: Added comprehensive error handling for:
  - JSON parsing in getEmployees() and getAllDuties()
  - Type validation in save operations
  - Date conversion in getDutiesForMonth()
  - Data validation in saveDutiesForMonth()
  - Export/import operations

Benefits:
- Clear error messages in German for better user experience
- Graceful degradation when data is corrupted
- Type checking to prevent invalid data from being stored
- Row-level error reporting for Excel processing
- Invalid data filtering to prevent application crashes
This commit is contained in:
Claude 2025-12-13 13:31:18 +00:00
parent 8821bee816
commit b9d8e7094b
No known key found for this signature in database
6 changed files with 534 additions and 270 deletions

View file

@ -284,9 +284,26 @@ def _populate_checks(ws):
def build_template(): def build_template():
"""Builds the complete Excel template with all sheets and formulas."""
try:
# Create output directory
try:
TEMPLATE_PATH.parent.mkdir(parents=True, exist_ok=True) TEMPLATE_PATH.parent.mkdir(parents=True, exist_ok=True)
wb = Workbook() except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Erstellen des Verzeichnisses '{TEMPLATE_PATH.parent}'")
raise
except OSError as e:
print(f"❌ Fehler beim Erstellen des Verzeichnisses '{TEMPLATE_PATH.parent}': {e}")
raise
# Create workbook
try:
wb = Workbook()
except Exception as e:
print(f"❌ Fehler beim Erstellen des Workbooks: {e}")
raise
try:
readme_ws = wb.active readme_ws = wb.active
readme_ws.title = "README" readme_ws.title = "README"
_populate_readme(readme_ws) _populate_readme(readme_ws)
@ -305,12 +322,33 @@ def build_template():
checks_ws = wb.create_sheet("Checks") checks_ws = wb.create_sheet("Checks")
_populate_checks(checks_ws) _populate_checks(checks_ws)
except Exception as e:
print(f"❌ Fehler beim Erstellen der Arbeitsblätter: {e}")
raise
# Save template
try:
wb.save(TEMPLATE_PATH) wb.save(TEMPLATE_PATH)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{TEMPLATE_PATH}'")
raise
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{TEMPLATE_PATH}': {e}")
raise
return TEMPLATE_PATH return TEMPLATE_PATH
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Erstellen der Vorlage: {e}")
raise
if __name__ == "__main__": if __name__ == "__main__":
try:
path = build_template() path = build_template()
print(f"✅ Vorlage (Variante 2 streng) erstellt: {path}") print(f"✅ Vorlage (Variante 2 streng) erstellt: {path}")
except Exception:
# Error already printed in build_template
import sys
sys.exit(1)

View file

@ -20,24 +20,38 @@ ABZUG = 2.0 # Abzug nach Erreichen der Schwelle
def load_holidays(wb): def load_holidays(wb):
"""Lädt Feiertage aus dem Feiertage-Blatt.""" """Lädt Feiertage aus dem Feiertage-Blatt."""
if "Feiertage" not in wb.sheetnames: if "Feiertage" not in wb.sheetnames:
print("⚠️ Warnung: Blatt 'Feiertage' nicht gefunden. Keine Feiertage geladen")
return set() return set()
holidays = set() holidays = set()
try:
ws = wb["Feiertage"] ws = wb["Feiertage"]
for row in ws.iter_rows(min_row=2, values_only=True): for row_num, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2):
if row[0] and row[2] == "NRW": # Datum und BL prüfen try:
if row[0] and len(row) > 2 and row[2] == "NRW": # Datum und BL prüfen
date_raw = row[0] date_raw = row[0]
if isinstance(date_raw, str): if isinstance(date_raw, str):
try: try:
parsed_date = datetime.strptime(date_raw, '%d.%m.%Y').date() parsed_date = datetime.strptime(date_raw, '%d.%m.%Y').date()
holidays.add(parsed_date) holidays.add(parsed_date)
except: except ValueError as e:
pass print(f"⚠️ Warnung: Ungültiges Datumsformat in Zeile {row_num}: '{date_raw}' - {e}")
continue
elif isinstance(date_raw, datetime): elif isinstance(date_raw, datetime):
holidays.add(date_raw.date()) holidays.add(date_raw.date())
elif isinstance(date_raw, date): elif isinstance(date_raw, date):
holidays.add(date_raw) holidays.add(date_raw)
except IndexError:
print(f"⚠️ Warnung: Unvollständige Zeile {row_num} im Feiertage-Blatt übersprungen")
continue
except Exception as e:
print(f"⚠️ Warnung: Fehler beim Verarbeiten von Zeile {row_num}: {e}")
continue
except Exception as e:
print(f"❌ Fehler beim Laden der Feiertage: {e}")
return set()
return holidays return holidays
@ -155,8 +169,20 @@ def calculate_verguetung(plan_data, holidays):
def process_file(filepath): def process_file(filepath):
"""Verarbeitet die Excel-Datei und schreibt Auswertung.""" """Verarbeitet die Excel-Datei und schreibt Auswertung."""
# Load workbook
try:
wb = load_workbook(filepath) wb = load_workbook(filepath)
except FileNotFoundError:
print(f"❌ Fehler: Datei '{filepath}' nicht gefunden")
return
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{filepath}'")
return
except Exception as e:
print(f"❌ Fehler beim Laden der Datei '{filepath}': {e}")
return
try:
# Lade Feiertage # Lade Feiertage
holidays = load_holidays(wb) holidays = load_holidays(wb)
print(f"📅 {len(holidays)} Feiertage geladen") print(f"📅 {len(holidays)} Feiertage geladen")
@ -169,7 +195,8 @@ def process_file(filepath):
plan_ws = wb["Plan"] plan_ws = wb["Plan"]
plan_data = [] plan_data = []
for row in plan_ws.iter_rows(min_row=2, values_only=True): for row_num, row in enumerate(plan_ws.iter_rows(min_row=2, values_only=True), start=2):
try:
if row[0]: # Wenn Datum vorhanden if row[0]: # Wenn Datum vorhanden
datum_raw = row[0] datum_raw = row[0]
mitarbeiter = row[1] if len(row) > 1 else None mitarbeiter = row[1] if len(row) > 1 else None
@ -178,28 +205,41 @@ def process_file(filepath):
if isinstance(datum_raw, str): if isinstance(datum_raw, str):
try: try:
datum = datetime.strptime(datum_raw, '%d.%m.%Y').date() datum = datetime.strptime(datum_raw, '%d.%m.%Y').date()
except: except ValueError as e:
print(f"⚠️ Warnung: Ungültiges Datumsformat in Zeile {row_num}: '{datum_raw}' - übersprungen")
continue continue
elif isinstance(datum_raw, datetime): elif isinstance(datum_raw, datetime):
datum = datum_raw.date() datum = datum_raw.date()
elif isinstance(datum_raw, date): elif isinstance(datum_raw, date):
datum = datum_raw datum = datum_raw
else: else:
print(f"⚠️ Warnung: Unbekannter Datumstyp in Zeile {row_num}: {type(datum_raw)} - übersprungen")
continue continue
if mitarbeiter: if mitarbeiter:
plan_data.append((datum, mitarbeiter)) plan_data.append((datum, mitarbeiter))
except Exception as e:
print(f"⚠️ Warnung: Fehler beim Verarbeiten von Plan-Zeile {row_num}: {e}")
continue
print(f"📋 {len(plan_data)} Einträge im Plan") print(f"📋 {len(plan_data)} Einträge im Plan")
if not plan_data:
print("⚠️ Warnung: Keine gültigen Plan-Einträge gefunden")
# Berechne Vergütung # Berechne Vergütung
try:
results = calculate_verguetung(plan_data, holidays) results = calculate_verguetung(plan_data, holidays)
except Exception as e:
print(f"❌ Fehler bei der Vergütungsberechnung: {e}")
return
# Schreibe Auswertung # Schreibe Auswertung
if "Auswertung" not in wb.sheetnames: if "Auswertung" not in wb.sheetnames:
print("❌ Blatt 'Auswertung' nicht gefunden!") print("❌ Blatt 'Auswertung' nicht gefunden!")
return return
try:
auswertung_ws = wb["Auswertung"] auswertung_ws = wb["Auswertung"]
# Lösche alte Daten (ab Zeile 2) # Lösche alte Daten (ab Zeile 2)
@ -225,8 +265,20 @@ def process_file(filepath):
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid") auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
else: else:
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid") auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
except Exception as e:
print(f"❌ Fehler beim Schreiben der Auswertung: {e}")
return
# Save file
try:
wb.save(filepath) wb.save(filepath)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{filepath}'")
return
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{filepath}': {e}")
return
print(f"\n✅ Auswertung geschrieben: {len(results)} Mitarbeiter") print(f"\n✅ Auswertung geschrieben: {len(results)} Mitarbeiter")
print(f" Datei: {filepath}") print(f" Datei: {filepath}")
@ -238,6 +290,10 @@ def process_file(filepath):
print(f"{r['mitarbeiter']:<20} {r['wt_einheiten']:>6.1f} {r['we_gesamt']:>6.1f} {r['schwelle_erreicht']:<10} {r['auszahlung_gesamt']:>9.2f}") print(f"{r['mitarbeiter']:<20} {r['wt_einheiten']:>6.1f} {r['we_gesamt']:>6.1f} {r['schwelle_erreicht']:<10} {r['auszahlung_gesamt']:>9.2f}")
print(f"{'='*70}") print(f"{'='*70}")
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Verarbeiten der Datei: {e}")
return
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) >= 2: if len(sys.argv) >= 2:

View file

@ -15,8 +15,29 @@ def fill_plan_with_dates(template_path, output_path, year, month):
Lädt die Vorlage und füllt Spalte A (Datum) im Plan-Blatt Lädt die Vorlage und füllt Spalte A (Datum) im Plan-Blatt
mit allen Tagen des angegebenen Monats. mit allen Tagen des angegebenen Monats.
""" """
wb = load_workbook(template_path) # Validate input parameters
if not (1 <= month <= 12):
print(f"❌ Fehler: Ungültiger Monat '{month}'. Monat muss zwischen 1 und 12 liegen")
return
if year < 1900 or year > 2100:
print(f"❌ Fehler: Ungültiges Jahr '{year}'. Jahr muss zwischen 1900 und 2100 liegen")
return
# Load template workbook
try:
wb = load_workbook(template_path)
except FileNotFoundError:
print(f"❌ Fehler: Vorlagendatei '{template_path}' nicht gefunden")
return
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{template_path}'")
return
except Exception as e:
print(f"❌ Fehler beim Laden der Vorlagendatei '{template_path}': {e}")
return
try:
# Regeln-Blatt: Monat_Auswahl setzen # Regeln-Blatt: Monat_Auswahl setzen
if "Regeln" in wb.sheetnames: if "Regeln" in wb.sheetnames:
regeln_ws = wb["Regeln"] regeln_ws = wb["Regeln"]
@ -31,13 +52,21 @@ def fill_plan_with_dates(template_path, output_path, year, month):
plan_ws = wb["Plan"] plan_ws = wb["Plan"]
# Startdatum # Startdatum
try:
start_date = date(year, month, 1) start_date = date(year, month, 1)
except ValueError as e:
print(f"❌ Fehler: Ungültiges Datum für Jahr {year}, Monat {month}: {e}")
return
# Letzter Tag des Monats # Letzter Tag des Monats
try:
if month == 12: if month == 12:
end_date = date(year + 1, 1, 1) - timedelta(days=1) end_date = date(year + 1, 1, 1) - timedelta(days=1)
else: else:
end_date = date(year, month + 1, 1) - timedelta(days=1) end_date = date(year, month + 1, 1) - timedelta(days=1)
except ValueError as e:
print(f"❌ Fehler beim Berechnen des Enddatums: {e}")
return
# Alle Tage durchgehen # Alle Tage durchgehen
current_date = start_date current_date = start_date
@ -51,11 +80,24 @@ def fill_plan_with_dates(template_path, output_path, year, month):
current_date += timedelta(days=1) current_date += timedelta(days=1)
row += 1 row += 1
# Save output file
try:
wb.save(output_path) wb.save(output_path)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{output_path}'")
return
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{output_path}': {e}")
return
print(f"✅ Plan-Blatt vorbefüllt für {month:02d}/{year}") print(f"✅ Plan-Blatt vorbefüllt für {month:02d}/{year}")
print(f" Ausgabe: {output_path}") print(f" Ausgabe: {output_path}")
print(f" Trage jetzt nur noch in Spalte B (Mitarbeiter) und C (Anteil) die Namen ein!") print(f" Trage jetzt nur noch in Spalte B (Mitarbeiter) und C (Anteil) die Namen ein!")
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Füllen des Plan-Blatts: {e}")
return
if __name__ == "__main__": if __name__ == "__main__":
template = Path("templates/Dienstplan_Vorlage_V2_NRW.xlsx") template = Path("templates/Dienstplan_Vorlage_V2_NRW.xlsx")

View file

@ -12,6 +12,7 @@ from datetime import datetime
def create_example_excel(): def create_example_excel():
"""Erstellt eine Beispiel-Excel-Datei mit formatierten Daten.""" """Erstellt eine Beispiel-Excel-Datei mit formatierten Daten."""
try:
# Neues Workbook erstellen # Neues Workbook erstellen
wb = Workbook() wb = Workbook()
ws = wb.active ws = wb.active
@ -49,15 +50,33 @@ def create_example_excel():
# Ausgabeverzeichnis erstellen # Ausgabeverzeichnis erstellen
output_dir = Path("output") output_dir = Path("output")
try:
output_dir.mkdir(exist_ok=True) output_dir.mkdir(exist_ok=True)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Erstellen des Verzeichnisses '{output_dir}'")
raise
except OSError as e:
print(f"❌ Fehler beim Erstellen des Verzeichnisses '{output_dir}': {e}")
raise
# Datei speichern # Datei speichern
output_file = output_dir / f"example_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx" output_file = output_dir / f"example_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
try:
wb.save(output_file) wb.save(output_file)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{output_file}'")
raise
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{output_file}': {e}")
raise
print(f"Excel-Datei erfolgreich erstellt: {output_file}") print(f"Excel-Datei erfolgreich erstellt: {output_file}")
return output_file return output_file
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Erstellen der Excel-Datei: {e}")
raise
if __name__ == "__main__": if __name__ == "__main__":
create_example_excel() create_example_excel()

View file

@ -10,9 +10,21 @@ from pathlib import Path
def read_excel_to_dict(filepath): def read_excel_to_dict(filepath):
"""Liest eine Excel-Datei und gibt die Daten als Dictionary zurück.""" """Liest eine Excel-Datei und gibt die Daten als Dictionary zurück."""
try:
wb = load_workbook(filepath, data_only=True) wb = load_workbook(filepath, data_only=True)
except FileNotFoundError:
print(f"❌ Fehler: Datei '{filepath}' nicht gefunden")
raise
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{filepath}'")
raise
except Exception as e:
print(f"❌ Fehler beim Laden der Excel-Datei '{filepath}': {e}")
raise
result = {} result = {}
try:
for sheet_name in wb.sheetnames: for sheet_name in wb.sheetnames:
ws = wb[sheet_name] ws = wb[sheet_name]
@ -24,6 +36,9 @@ def read_excel_to_dict(filepath):
data.append(list(row)) data.append(list(row))
result[sheet_name] = data result[sheet_name] = data
except Exception as e:
print(f"❌ Fehler beim Lesen der Daten aus der Excel-Datei: {e}")
raise
return result return result
@ -35,8 +50,13 @@ def print_excel_content(filepath):
print(f"Excel-Datei: {filepath}") print(f"Excel-Datei: {filepath}")
print(f"{'='*60}\n") print(f"{'='*60}\n")
try:
data = read_excel_to_dict(filepath) data = read_excel_to_dict(filepath)
except Exception:
# Error already printed in read_excel_to_dict
raise
try:
for sheet_name, rows in data.items(): for sheet_name, rows in data.items():
print(f"\n📊 Sheet: {sheet_name}") print(f"\n📊 Sheet: {sheet_name}")
print(f"{'-'*60}") print(f"{'-'*60}")
@ -54,7 +74,14 @@ def print_excel_content(filepath):
# Als JSON ausgeben # Als JSON ausgeben
print("📄 JSON-Format:") print("📄 JSON-Format:")
try:
print(json.dumps(data, indent=2, ensure_ascii=False)) print(json.dumps(data, indent=2, ensure_ascii=False))
except (TypeError, ValueError) as e:
print(f"❌ Fehler beim Konvertieren zu JSON: {e}")
raise
except Exception as e:
print(f"❌ Fehler beim Ausgeben der Excel-Daten: {e}")
raise
return data return data

View file

@ -13,8 +13,21 @@ class DataStorage {
* @returns {Array} Array of employee names * @returns {Array} Array of employee names
*/ */
getEmployees() { getEmployees() {
try {
const data = localStorage.getItem(this.STORAGE_KEY_EMPLOYEES); const data = localStorage.getItem(this.STORAGE_KEY_EMPLOYEES);
return data ? JSON.parse(data) : []; if (!data) {
return [];
}
const parsed = JSON.parse(data);
if (!Array.isArray(parsed)) {
console.error('Fehler: Mitarbeiter-Daten sind kein Array. Zurücksetzen auf leeres Array');
return [];
}
return parsed;
} catch (e) {
console.error('Fehler beim Laden der Mitarbeiter-Daten:', e);
return [];
}
} }
/** /**
@ -22,7 +35,16 @@ class DataStorage {
* @param {Array} employees - Array of employee names * @param {Array} employees - Array of employee names
*/ */
saveEmployees(employees) { saveEmployees(employees) {
try {
if (!Array.isArray(employees)) {
console.error('Fehler: employees muss ein Array sein');
throw new TypeError('employees muss ein Array sein');
}
localStorage.setItem(this.STORAGE_KEY_EMPLOYEES, JSON.stringify(employees)); localStorage.setItem(this.STORAGE_KEY_EMPLOYEES, JSON.stringify(employees));
} catch (e) {
console.error('Fehler beim Speichern der Mitarbeiter-Daten:', e);
throw e;
}
} }
/** /**
@ -63,8 +85,21 @@ class DataStorage {
* @returns {Object} Object with structure: {employeeName: {year-month: [duties]}} * @returns {Object} Object with structure: {employeeName: {year-month: [duties]}}
*/ */
getAllDuties() { getAllDuties() {
try {
const data = localStorage.getItem(this.STORAGE_KEY_DUTIES); const data = localStorage.getItem(this.STORAGE_KEY_DUTIES);
return data ? JSON.parse(data) : {}; if (!data) {
return {};
}
const parsed = JSON.parse(data);
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
console.error('Fehler: Dienst-Daten sind kein gültiges Objekt. Zurücksetzen auf leeres Objekt');
return {};
}
return parsed;
} catch (e) {
console.error('Fehler beim Laden der Dienst-Daten:', e);
return {};
}
} }
/** /**
@ -72,7 +107,16 @@ class DataStorage {
* @param {Object} duties * @param {Object} duties
*/ */
saveAllDuties(duties) { saveAllDuties(duties) {
try {
if (typeof duties !== 'object' || duties === null || Array.isArray(duties)) {
console.error('Fehler: duties muss ein gültiges Objekt sein');
throw new TypeError('duties muss ein gültiges Objekt sein');
}
localStorage.setItem(this.STORAGE_KEY_DUTIES, JSON.stringify(duties)); localStorage.setItem(this.STORAGE_KEY_DUTIES, JSON.stringify(duties));
} catch (e) {
console.error('Fehler beim Speichern der Dienst-Daten:', e);
throw e;
}
} }
/** /**
@ -83,6 +127,7 @@ class DataStorage {
* @returns {Array} Array of duty objects * @returns {Array} Array of duty objects
*/ */
getDutiesForMonth(employeeName, year, month) { getDutiesForMonth(employeeName, year, month) {
try {
const allDuties = this.getAllDuties(); const allDuties = this.getAllDuties();
const monthKey = `${year}-${String(month).padStart(2, '0')}`; const monthKey = `${year}-${String(month).padStart(2, '0')}`;
@ -91,10 +136,26 @@ class DataStorage {
} }
// Convert date strings back to Date objects // Convert date strings back to Date objects
return allDuties[employeeName][monthKey].map(duty => ({ return allDuties[employeeName][monthKey].map(duty => {
try {
const dateObj = new Date(duty.date);
if (isNaN(dateObj.getTime())) {
console.error(`Fehler: Ungültiges Datum für Dienst: ${duty.date}`);
return null;
}
return {
...duty, ...duty,
date: new Date(duty.date) date: dateObj
})); };
} catch (e) {
console.error('Fehler beim Konvertieren des Datums:', e);
return null;
}
}).filter(duty => duty !== null); // Filter out invalid entries
} catch (e) {
console.error('Fehler beim Laden der Dienste für Monat:', e);
return [];
}
} }
/** /**
@ -105,6 +166,12 @@ class DataStorage {
* @param {Array} duties - Array of duty objects * @param {Array} duties - Array of duty objects
*/ */
saveDutiesForMonth(employeeName, year, month, duties) { saveDutiesForMonth(employeeName, year, month, duties) {
try {
if (!Array.isArray(duties)) {
console.error('Fehler: duties muss ein Array sein');
throw new TypeError('duties muss ein Array sein');
}
const allDuties = this.getAllDuties(); const allDuties = this.getAllDuties();
const monthKey = `${year}-${String(month).padStart(2, '0')}`; const monthKey = `${year}-${String(month).padStart(2, '0')}`;
@ -113,12 +180,22 @@ class DataStorage {
} }
// Convert Date objects to strings for storage // Convert Date objects to strings for storage
allDuties[employeeName][monthKey] = duties.map(duty => ({ allDuties[employeeName][monthKey] = duties.map(duty => {
if (!duty.date || !(duty.date instanceof Date)) {
console.error('Fehler: Dienst hat kein gültiges Datum:', duty);
throw new TypeError('Dienst muss ein gültiges Date-Objekt haben');
}
return {
...duty, ...duty,
date: duty.date.toISOString() date: duty.date.toISOString()
})); };
});
this.saveAllDuties(allDuties); this.saveAllDuties(allDuties);
} catch (e) {
console.error('Fehler beim Speichern der Dienste für Monat:', e);
throw e;
}
} }
/** /**
@ -196,10 +273,15 @@ class DataStorage {
* @returns {string} JSON string * @returns {string} JSON string
*/ */
exportData() { exportData() {
try {
return JSON.stringify({ return JSON.stringify({
employees: this.getEmployees(), employees: this.getEmployees(),
duties: this.getAllDuties() duties: this.getAllDuties()
}, null, 2); }, null, 2);
} catch (e) {
console.error('Fehler beim Exportieren der Daten:', e);
throw new Error('Fehler beim Exportieren der Daten: ' + e.message);
}
} }
/** /**