From 2d59cb6497e1b4b45bedc44469db03b19acae62d Mon Sep 17 00:00:00 2001 From: Dominick Leppich Date: Tue, 10 Sep 2024 09:15:51 +0200 Subject: [PATCH] fix: error handling for record import --- .../service/io/TabularRecordImporter.java | 32 +++++++++---------- .../manager/VocabularyImportManager.java | 1 - .../exception/VocabularyException.java | 3 ++ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/module-core/src/main/java/io/goobi/vocabulary/service/io/TabularRecordImporter.java b/module-core/src/main/java/io/goobi/vocabulary/service/io/TabularRecordImporter.java index 5211193..6b43dac 100644 --- a/module-core/src/main/java/io/goobi/vocabulary/service/io/TabularRecordImporter.java +++ b/module-core/src/main/java/io/goobi/vocabulary/service/io/TabularRecordImporter.java @@ -1,5 +1,6 @@ package io.goobi.vocabulary.service.io; +import io.goobi.vocabulary.exception.VocabularyException; import io.goobi.vocabulary.exchange.FieldInstance; import io.goobi.vocabulary.exchange.FieldValue; import io.goobi.vocabulary.exchange.TranslationInstance; @@ -53,22 +54,21 @@ public List fromTabularData(VocabularyEntity vocabulary, List< List header = data.get(0); parseHeader(header); validateHeader(); - List importErrors = new LinkedList<>(); + List importErrors = new LinkedList<>(); // parse all records and create a queue List result = new LinkedList<>(); for (int i = 1; i < data.size(); i++) { try { result.add(parseRecord(data.get(i))); - } catch (IllegalArgumentException e) { + } catch (VocabularyException e) { importErrors.add(e); } } if (!importErrors.isEmpty()) { - // TODO: Use VocabularyException - throw new IllegalArgumentException("Error(s) during tabular data parsing:\n\t" - + importErrors.stream().map(Throwable::getMessage).collect(Collectors.joining("\n\t"))); + throw new VocabularyException(VocabularyException.ErrorCode.RecordImportParsingIssues, importErrors, null, + params -> "Errors during record parsing"); } return result; @@ -113,7 +113,7 @@ private void validateHeader() { .map(l -> new FieldInformation(name, l)); }) .collect(Collectors.toSet())); - Set presentFields = fields.stream().collect(Collectors.toSet()); + Set presentFields = new HashSet<>(fields); if (!definedFields.equals(presentFields)) { Set undefined = presentFields.stream() .filter(f -> !definedFields.contains(f)) @@ -121,15 +121,11 @@ private void validateHeader() { Set missing = definedFields.stream() .filter(f -> !presentFields.contains(f)) .collect(Collectors.toSet()); - String error = "Given fields do not match vocabulary schema:"; - if (!undefined.isEmpty()) { - error += "\n\tUndefined fields: " + undefined.stream().map(FieldInformation::toString).collect(Collectors.joining(", ")); - } - if (!missing.isEmpty()) { - error += "\n\tMissing fields: " + missing.stream().map(FieldInformation::toString).collect(Collectors.joining(", ")); - } - // TODO: Use VocabularyException - throw new IllegalArgumentException(error); + throw new VocabularyException(VocabularyException.ErrorCode.RecordImportHeaderIssues, null, Map.of( + "undefinedFields", undefined.stream().map(FieldInformation::toString).collect(Collectors.joining(",")), + "missingFields", missing.stream().map(FieldInformation::toString).collect(Collectors.joining(",")) + ), + params -> "Given fields do not match vocabulary schema, undefined fields \"" + params.get("undefinedFields") + "\", missing fields \"" + params.get("missingFields") + "\""); } } @@ -137,7 +133,11 @@ private VocabularyRecord parseRecord(List rec) { VocabularyRecord resultRecord = new VocabularyRecord(); if (rec.size() != fields.size()) { - throw new IllegalArgumentException("Malformed tabular data, number of fields does not match header"); + throw new VocabularyException(VocabularyException.ErrorCode.RecordImportFieldCountIssue, null, Map.of( + "expectedSize", String.valueOf(fields.size()), + "realSize", String.valueOf(rec.size()) + ), + params -> "Malformed tabular data, number of fields does not match header. Header size \"" + params.get("expectedSize") + "\", data row size \"" + params.get("realSize") + "\""); } Map fieldMap = new HashMap<>(); diff --git a/module-core/src/main/java/io/goobi/vocabulary/service/manager/VocabularyImportManager.java b/module-core/src/main/java/io/goobi/vocabulary/service/manager/VocabularyImportManager.java index 0eac6e7..c1effba 100644 --- a/module-core/src/main/java/io/goobi/vocabulary/service/manager/VocabularyImportManager.java +++ b/module-core/src/main/java/io/goobi/vocabulary/service/manager/VocabularyImportManager.java @@ -124,7 +124,6 @@ private void performRecordImport(List insertionQueue) { } } if (!importErrors.isEmpty()) { - // TODO: Use VocabularyException throw new VocabularyException(RecordImport, importErrors, null, params -> "Error(s) during tabular import:\n\t" + importErrors.stream().map(Throwable::getMessage).collect(Collectors.joining("\n\t"))); } diff --git a/module-exchange/src/main/java/io/goobi/vocabulary/exception/VocabularyException.java b/module-exchange/src/main/java/io/goobi/vocabulary/exception/VocabularyException.java index 04c454e..ef1086f 100644 --- a/module-exchange/src/main/java/io/goobi/vocabulary/exception/VocabularyException.java +++ b/module-exchange/src/main/java/io/goobi/vocabulary/exception/VocabularyException.java @@ -40,6 +40,9 @@ public enum ErrorCode { RecordValidationChildrenReferencesNotAllowed, RecordValidationSingleRootElementVocabularyAlreadyContainsRecord, RecordImport, + RecordImportHeaderIssues, + RecordImportParsingIssues, + RecordImportFieldCountIssue, RecordImportUnsupportedExcelCellType, FieldInstanceIssues, FieldInstanceIsEmpty,