mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
[YAML Thing Provider] Log warning on Thing config errors (#5282)
Catch IAE during Thing configuration loading to prevent the entire file from failing. Errors are now logged as warnings instead of throwing a full stack trace. Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
+9
@@ -18,6 +18,7 @@ import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.model.yaml.internal.util.YamlElementUtils;
|
||||
import org.openhab.core.thing.type.ChannelKind;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
@@ -42,6 +43,14 @@ public class YamlChannelDTO {
|
||||
|
||||
public boolean isValid(@NonNull List<@NonNull String> errors, @NonNull List<@NonNull String> warnings) {
|
||||
boolean ok = true;
|
||||
if (config != null) {
|
||||
try {
|
||||
new Configuration(config);
|
||||
} catch (IllegalArgumentException e) {
|
||||
errors.add("invalid data in \"config\" field: %s".formatted(e.getMessage()));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (type != null) {
|
||||
try {
|
||||
new ChannelTypeUID("dummy", type);
|
||||
|
||||
+10
@@ -19,6 +19,7 @@ import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.model.yaml.YamlElement;
|
||||
import org.openhab.core.model.yaml.YamlElementName;
|
||||
import org.openhab.core.model.yaml.internal.util.YamlElementUtils;
|
||||
@@ -92,6 +93,15 @@ public class YamlThingDTO implements YamlElement, Cloneable {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (config != null) {
|
||||
try {
|
||||
new Configuration(config);
|
||||
} catch (IllegalArgumentException e) {
|
||||
addToList(errors,
|
||||
"invalid thing \"%s\": invalid data in \"config\" field: %s".formatted(uid, e.getMessage()));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (channels != null) {
|
||||
for (Map.Entry<@NonNull String, @NonNull YamlChannelDTO> entry : channels.entrySet()) {
|
||||
String channelId = entry.getKey();
|
||||
|
||||
+41
-36
@@ -350,49 +350,54 @@ public class YamlThingProvider extends AbstractProvider<Thing>
|
||||
}
|
||||
|
||||
private @Nullable Thing mapThing(YamlThingDTO thingDto) {
|
||||
ThingUID thingUID = new ThingUID(thingDto.uid);
|
||||
String[] segments = thingUID.getAsString().split(AbstractUID.SEPARATOR);
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID(thingUID.getBindingId(), segments[1]);
|
||||
try {
|
||||
ThingUID thingUID = new ThingUID(thingDto.uid);
|
||||
String[] segments = thingUID.getAsString().split(AbstractUID.SEPARATOR);
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID(thingUID.getBindingId(), segments[1]);
|
||||
|
||||
ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID, localeProvider.getLocale());
|
||||
ThingUID bridgeUID = thingDto.bridge != null ? new ThingUID(thingDto.bridge) : null;
|
||||
Configuration configuration = new Configuration(thingDto.config);
|
||||
ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID, localeProvider.getLocale());
|
||||
ThingUID bridgeUID = thingDto.bridge != null ? new ThingUID(thingDto.bridge) : null;
|
||||
Configuration configuration = new Configuration(thingDto.config);
|
||||
|
||||
ThingBuilder thingBuilder = thingDto.isBridge() ? BridgeBuilder.create(thingTypeUID, thingUID)
|
||||
: ThingBuilder.create(thingTypeUID, thingUID);
|
||||
thingBuilder
|
||||
.withLabel(thingDto.label != null ? thingDto.label : (thingType != null ? thingType.getLabel() : null));
|
||||
thingBuilder.withLocation(thingDto.location);
|
||||
thingBuilder.withBridge(bridgeUID);
|
||||
thingBuilder.withConfiguration(configuration);
|
||||
ThingBuilder thingBuilder = thingDto.isBridge() ? BridgeBuilder.create(thingTypeUID, thingUID)
|
||||
: ThingBuilder.create(thingTypeUID, thingUID);
|
||||
thingBuilder.withLabel(
|
||||
thingDto.label != null ? thingDto.label : (thingType != null ? thingType.getLabel() : null));
|
||||
thingBuilder.withLocation(thingDto.location);
|
||||
thingBuilder.withBridge(bridgeUID);
|
||||
thingBuilder.withConfiguration(configuration);
|
||||
|
||||
List<Channel> channels = createChannels(thingTypeUID, thingUID,
|
||||
thingDto.channels != null ? thingDto.channels : Map.of(),
|
||||
thingType != null ? thingType.getChannelDefinitions() : List.of());
|
||||
thingBuilder.withChannels(channels);
|
||||
List<Channel> channels = createChannels(thingTypeUID, thingUID,
|
||||
thingDto.channels != null ? thingDto.channels : Map.of(),
|
||||
thingType != null ? thingType.getChannelDefinitions() : List.of());
|
||||
thingBuilder.withChannels(channels);
|
||||
|
||||
Thing thing = thingBuilder.build();
|
||||
Thing thing = thingBuilder.build();
|
||||
|
||||
Thing thingFromHandler = null;
|
||||
ThingHandlerFactory handlerFactory = thingHandlerFactories.stream()
|
||||
.filter(thf -> isThingHandlerFactoryReady(thf) && thf.supportsThingType(thingTypeUID)).findFirst()
|
||||
.orElse(null);
|
||||
if (handlerFactory != null) {
|
||||
thingFromHandler = handlerFactory.createThing(thingTypeUID, configuration, thingUID, bridgeUID);
|
||||
if (thingFromHandler != null) {
|
||||
mergeThing(thingFromHandler, thing);
|
||||
logger.debug("Successfully loaded thing \'{}\'", thingUID);
|
||||
} else {
|
||||
// Possible cause: Asynchronous loading of the XML files
|
||||
// Add the data to the queue in order to retry it later
|
||||
logger.debug(
|
||||
"ThingHandlerFactory \'{}\' claimed it can handle \'{}\' type but actually did not. Queued for later refresh.",
|
||||
handlerFactory.getClass().getSimpleName(), thingTypeUID);
|
||||
queueRetryThingCreation(handlerFactory, thingTypeUID, configuration, thingUID, bridgeUID);
|
||||
Thing thingFromHandler = null;
|
||||
ThingHandlerFactory handlerFactory = thingHandlerFactories.stream()
|
||||
.filter(thf -> isThingHandlerFactoryReady(thf) && thf.supportsThingType(thingTypeUID)).findFirst()
|
||||
.orElse(null);
|
||||
if (handlerFactory != null) {
|
||||
thingFromHandler = handlerFactory.createThing(thingTypeUID, configuration, thingUID, bridgeUID);
|
||||
if (thingFromHandler != null) {
|
||||
mergeThing(thingFromHandler, thing);
|
||||
logger.debug("Successfully loaded thing \'{}\'", thingUID);
|
||||
} else {
|
||||
// Possible cause: Asynchronous loading of the XML files
|
||||
// Add the data to the queue in order to retry it later
|
||||
logger.debug(
|
||||
"ThingHandlerFactory \'{}\' claimed it can handle \'{}\' type but actually did not. Queued for later refresh.",
|
||||
handlerFactory.getClass().getSimpleName(), thingTypeUID);
|
||||
queueRetryThingCreation(handlerFactory, thingTypeUID, configuration, thingUID, bridgeUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return thingFromHandler != null ? thingFromHandler : thing;
|
||||
return thingFromHandler != null ? thingFromHandler : thing;
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.warn("Error creating thing '{}', thing will be ignored: {}", thingDto.uid, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Channel> createChannels(ThingTypeUID thingTypeUID, ThingUID thingUID,
|
||||
|
||||
Reference in New Issue
Block a user