Skip to content

Improved error messages when reading and validating an invalid grid #1355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Updated dependabot workflow and added CODEOWNERS [#1328](https://github.com/ie3-institute/PowerSystemDataModel/issues/1328)
- Extend azimuth angle range to [-180°, 180°] for PV inputs [#1330](https://github.com/ie3-institute/PowerSystemDataModel/issues/1330)
- Improved error messages when reading and validating an invalid grid [#1354](https://github.com/ie3-institute/PowerSystemDataModel/issues/1354)

## [7.0.0] - 2025-05-08

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public DuplicateEntitiesException(
this(
"The following exception(s) occurred while checking the uniqueness of '"
+ entityName
+ "' entities: "
+ ExceptionUtils.getMessages(exceptions));
+ "' entities: \n"
+ ExceptionUtils.combineExceptions(exceptions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public FailedValidationException(String message) {

/** @param exceptions List of exceptions, which must not be empty */
public FailedValidationException(List<? extends Exception> exceptions) {
super(
"Validation failed due to: \n" + ExceptionUtils.getMessages(exceptions), exceptions.get(0));
super("Validation failed due to:\n " + ExceptionUtils.combineExceptions(exceptions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ public class InvalidEntityException extends ValidationException {
private static final long serialVersionUID = 809496087520306374L;

public InvalidEntityException(String faultDescription, UniqueEntity invalidEntity) {
super("Entity is invalid because of: \n" + faultDescription + " [" + invalidEntity + "]");
super("Entity is invalid because of: " + faultDescription + " [" + invalidEntity + "]");
}

public InvalidEntityException(
String faultDescription, Throwable cause, UniqueEntity invalidEntity) {
super(
"Entity is invalid because of: \n" + faultDescription + " [" + invalidEntity + "]", cause);
super("Entity is invalid because of: " + faultDescription + " [" + invalidEntity + "]", cause);
}

public InvalidEntityException(String message, Throwable cause) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ public SourceException(final String message) {
}

public SourceException(String message, List<? extends Exception> exceptions) {
super(message + " " + ExceptionUtils.getMessages(exceptions), exceptions.get(0));
super(message + "\n " + ExceptionUtils.combineExceptions(exceptions));
}
}
2 changes: 1 addition & 1 deletion src/main/java/edu/ie3/datamodel/io/factory/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public Try<R, FactoryException> get(D data) {
* {@link Failure}
*/
public Try<R, FactoryException> get(Try<D, ?> data) {
return data.transformF(FactoryException::new).flatMap(this::get);
return data.transformF(e -> new FactoryException(e.getMessage(), e)).flatMap(this::get);
}

/**
Expand Down
36 changes: 16 additions & 20 deletions src/main/java/edu/ie3/datamodel/io/processor/ProcessorProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package edu.ie3.datamodel.io.processor;

import edu.ie3.datamodel.exceptions.EntityProcessorException;
import edu.ie3.datamodel.exceptions.FailureException;
import edu.ie3.datamodel.exceptions.ProcessorProviderException;
import edu.ie3.datamodel.io.processor.input.InputEntityProcessor;
import edu.ie3.datamodel.io.processor.result.ResultEntityProcessor;
Expand Down Expand Up @@ -313,25 +312,22 @@ public static Collection<EntityProcessor<? extends Entity>> allResultEntityProce
Value,
Value>>
allTimeSeriesProcessors() throws EntityProcessorException {
try {
return Try.scanStream(
TimeSeriesProcessor.eligibleKeys.stream()
.map(
key ->
Try.of(
() ->
new TimeSeriesProcessor<>(
(Class<TimeSeries<TimeSeriesEntry<Value>, Value, Value>>)
key.getTimeSeriesClass(),
(Class<TimeSeriesEntry<Value>>) key.getEntryClass(),
(Class<Value>) key.getValueClass()),
EntityProcessorException.class)),
"list of processors")
.getOrThrow()
.collect(Collectors.toMap(TimeSeriesProcessor::getRegisteredKey, Function.identity()));
} catch (FailureException e) {
throw new EntityProcessorException(e.getCause());
}
return Try.scanStream(
TimeSeriesProcessor.eligibleKeys.stream()
.map(
key ->
Try.of(
() ->
new TimeSeriesProcessor<>(
(Class<TimeSeries<TimeSeriesEntry<Value>, Value, Value>>)
key.getTimeSeriesClass(),
(Class<TimeSeriesEntry<Value>>) key.getEntryClass(),
(Class<Value>) key.getValueClass()),
EntityProcessorException.class)),
"time series processors",
EntityProcessorException::new)
.getOrThrow()
.collect(Collectors.toMap(TimeSeriesProcessor::getRegisteredKey, Function.identity()));
}

@SuppressWarnings("unchecked cast")
Expand Down
37 changes: 16 additions & 21 deletions src/main/java/edu/ie3/datamodel/io/source/EntitySource.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,12 @@ protected static <E extends Entity, D extends EntityData> Stream<E> getEntities(
* @return a stream of the entity data wrapped in a {@link Try}
*/
protected static Stream<Try<EntityData, SourceException>> buildEntityData(
Class<? extends Entity> entityClass, DataSource dataSource) {
return Try.of(() -> dataSource.getSourceData(entityClass), SourceException.class)
.convert(
data ->
data.map(
fieldsToAttributes ->
new Try.Success<>(new EntityData(fieldsToAttributes, entityClass))),
exception -> Stream.of(Failure.of(exception)));
Class<? extends Entity> entityClass, DataSource dataSource) throws SourceException {
return dataSource
.getSourceData(entityClass)
.map(
fieldsToAttributes ->
new Try.Success<>(new EntityData(fieldsToAttributes, entityClass)));
}

/**
Expand All @@ -227,7 +225,8 @@ protected static Stream<Try<EntityData, SourceException>> buildEntityData(
protected static <E extends EntityData> Stream<Try<E, SourceException>> buildEntityData(
Class<? extends Entity> entityClass,
DataSource dataSource,
WrappedFunction<EntityData, E> converter) {
WrappedFunction<EntityData, E> converter)
throws SourceException {
return buildEntityData(entityClass, dataSource).map(converter);
}

Expand Down Expand Up @@ -356,9 +355,7 @@ Function<Pair<E, T>, R> enrichFunction(
*/
protected static <S, E extends Exception> Stream<S> unpack(
Stream<Try<S, E>> inputStream, Class<S> clazz) throws SourceException {
return Try.scanStream(inputStream, clazz.getSimpleName())
.transformF(SourceException::new)
.getOrThrow();
return Try.scanStream(inputStream, clazz.getSimpleName(), SourceException::new).getOrThrow();
}

/**
Expand All @@ -376,16 +373,14 @@ protected static <E extends EntityData, R> Try<R, SourceException> extractFuncti
return entityData.flatMap(
data ->
Try.of(() -> data.getUUID(fieldName), FactoryException.class)
.flatMap(entityUuid -> extractFunction(entityUuid, entities))
.transformF(
exception ->
new SourceException(
"Extracting UUID field "
"Extracting UUID for field '"
+ fieldName
+ " from entity data "
+ entityData
+ " failed.",
exception))
.flatMap(entityUuid -> extractFunction(entityUuid, entities)));
+ "' failed. Caused by: "
+ exception.getMessage())));
}

/**
Expand All @@ -396,13 +391,13 @@ protected static <E extends EntityData, R> Try<R, SourceException> extractFuncti
* @return a try of the {@link Entity}
* @param <T> type of entity
*/
protected static <T> Try<T, SourceException> extractFunction(UUID uuid, Map<UUID, T> entityMap) {
protected static <T> Try<T, FactoryException> extractFunction(UUID uuid, Map<UUID, T> entityMap) {
return Optional.ofNullable(entityMap.get(uuid))
// We either find a matching entity for given UUID, thus return a success
.map(entity -> Try.of(() -> entity, SourceException.class))
.map(entity -> Try.of(() -> entity, FactoryException.class))
// ... or find no matching entity, returning a failure.
.orElse(
new Failure<>(new SourceException("Entity with uuid " + uuid + " was not provided.")));
new Failure<>(new FactoryException("Entity with uuid " + uuid + " was not provided.")));
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/edu/ie3/datamodel/io/source/GraphicSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ public void validate() throws ValidationException {
Stream.of(
validate(NodeGraphicInput.class, dataSource, nodeGraphicInputFactory),
validate(LineGraphicInput.class, dataSource, lineGraphicInputFactory)),
"Validation")
.transformF(FailedValidationException::new)
"Validation",
FailedValidationException::new)
.getOrThrow();
}

Expand Down Expand Up @@ -95,11 +95,13 @@ public GraphicElements getGraphicElements(Map<UUID, NodeInput> nodes, Map<UUID,
Try<Set<LineGraphicInput>, SourceException> lineGraphics =
Try.of(() -> getLineGraphicInput(lines), SourceException.class);

List<SourceException> exceptions = Try.getExceptions(List.of(nodeGraphics, lineGraphics));
List<SourceException> exceptions = Try.getExceptions(nodeGraphics, lineGraphics);

if (!exceptions.isEmpty()) {
throw new GraphicSourceException(
exceptions.size() + " error(s) occurred while initializing graphic elements. ",
"Exception(s) occurred in "
+ exceptions.size()
+ " input file(s) while initializing graphic elements. ",
exceptions);
} else {
// if everything is fine, return a GraphicElements instance
Expand Down
26 changes: 18 additions & 8 deletions src/main/java/edu/ie3/datamodel/io/source/RawGridSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@
*/
package edu.ie3.datamodel.io.source;

import edu.ie3.datamodel.exceptions.*;
import edu.ie3.datamodel.exceptions.FailedValidationException;
import edu.ie3.datamodel.exceptions.RawGridException;
import edu.ie3.datamodel.exceptions.SourceException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.io.factory.EntityData;
import edu.ie3.datamodel.io.factory.input.*;
import edu.ie3.datamodel.models.input.*;
import edu.ie3.datamodel.models.input.connector.*;
import edu.ie3.datamodel.models.input.MeasurementUnitInput;
import edu.ie3.datamodel.models.input.NodeInput;
import edu.ie3.datamodel.models.input.OperatorInput;
import edu.ie3.datamodel.models.input.connector.LineInput;
import edu.ie3.datamodel.models.input.connector.SwitchInput;
import edu.ie3.datamodel.models.input.connector.Transformer2WInput;
import edu.ie3.datamodel.models.input.connector.Transformer3WInput;
import edu.ie3.datamodel.models.input.connector.type.LineTypeInput;
import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput;
import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput;
Expand Down Expand Up @@ -62,8 +70,8 @@ public void validate() throws ValidationException {
validate(Transformer3WInput.class, dataSource, transformer3WInputFactory),
validate(SwitchInput.class, dataSource, switchInputFactory),
validate(MeasurementUnitInput.class, dataSource, measurementUnitInputFactory)),
"Validation")
.transformF(FailedValidationException::new)
"Validation",
FailedValidationException::new)
.getOrThrow();
}

Expand Down Expand Up @@ -146,12 +154,14 @@ public RawGridElements getGridData(
Try.of(() -> getMeasurementUnits(operators, nodes), SourceException.class);

List<SourceException> exceptions =
Try.getExceptions(
List.of(transformer2WInputs, transformer3WInputs, switches, measurementUnits));
Try.getExceptions(transformer2WInputs, transformer3WInputs, switches, measurementUnits);

if (!exceptions.isEmpty()) {
throw new RawGridException(
exceptions.size() + " error(s) occurred while initializing raw grid. ", exceptions);
"Exception(s) occurred in "
+ exceptions.size()
+ " input file(s) while initializing raw grid.",
exceptions);
} else {
/* build and return the grid if it is not empty */
// getOrThrow should not throw an exception in this context, because all exception are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ public void validate() throws ValidationException {
validate(FlexOptionsResult.class, dataSource, flexOptionsResultFactory),
validate(CongestionResult.class, dataSource, congestionResultFactory)));

Try.scanCollection(participantResults, Void.class)
.transformF(FailedValidationException::new)
.getOrThrow();
Try.scanCollection(participantResults, Void.class, FailedValidationException::new).getOrThrow();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ public void validate() throws ValidationException {
validate(StorageInput.class, dataSource, storageInputFactory),
validate(WecInput.class, dataSource, wecInputFactory),
validate(EvcsInput.class, dataSource, evcsInputFactory)),
"Validation")
.transformF(FailedValidationException::new)
"Validation",
FailedValidationException::new)
.getOrThrow();
}

Expand Down Expand Up @@ -212,21 +212,22 @@ public SystemParticipants getSystemParticipants(

List<SourceException> exceptions =
Try.getExceptions(
List.of(
fixedFeedInInputs,
pvInputs,
loads,
bmInputs,
storages,
wecInputs,
evs,
evcs,
chpInputs,
hpInputs));
fixedFeedInInputs,
pvInputs,
loads,
bmInputs,
storages,
wecInputs,
evs,
evcs,
chpInputs,
hpInputs);

if (!exceptions.isEmpty()) {
throw new SystemParticipantsException(
exceptions.size() + " error(s) occurred while initializing system participants. ",
"Exception(s) occurred in "
+ exceptions.size()
+ " input file(s) while initializing system participants.",
exceptions);
} else {
// if everything is fine, return a system participants container
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/edu/ie3/datamodel/io/source/ThermalSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public void validate() throws ValidationException {
dataSource,
domesticHotWaterStorageInputFactory),
validate(ThermalHouseInput.class, dataSource, thermalHouseInputFactory)),
"Validation")
.transformF(FailedValidationException::new)
"Validation",
FailedValidationException::new)
.getOrThrow();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ public void validate() throws ValidationException {
* @return That mapping
*/
public Map<UUID, UUID> getMapping() throws SourceException {
return Try.scanStream(getMappingSourceData().map(this::createMappingEntry), "MappingEntry")
.transform(
s -> s.collect(Collectors.toMap(MappingEntry::getAsset, MappingEntry::getTimeSeries)),
return Try.scanStream(
getMappingSourceData().map(this::createMappingEntry),
"MappingEntry",
SourceException::new)
.transformS(
s -> s.collect(Collectors.toMap(MappingEntry::getAsset, MappingEntry::getTimeSeries)))
.getOrThrow();
}

Expand Down
4 changes: 1 addition & 3 deletions src/main/java/edu/ie3/datamodel/io/source/TypeSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ public void validate() throws ValidationException {
validate(Transformer2WTypeInput.class, dataSource, transformer2WTypeInputFactory),
validate(Transformer3WTypeInput.class, dataSource, transformer3WTypeInputFactory)));

Try.scanCollection(participantResults, Void.class)
.transformF(FailedValidationException::new)
.getOrThrow();
Try.scanCollection(participantResults, Void.class, FailedValidationException::new).getOrThrow();
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ protected List<TimeBasedValue<WeatherValue>> buildTimeBasedValues(
return factory.get(
Try.from(data, () -> new SourceException("Missing data in: " + data)));
}),
"TimeBasedValue<WeatherValue>")
.transform(Stream::toList, SourceException::new)
"TimeBasedValue<WeatherValue>",
SourceException::new)
.transformS(Stream::toList)
.getOrThrow();
}
}
Loading