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.NonNull;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.model.yaml.internal.util.YamlElementUtils;
|
||||||
import org.openhab.core.thing.type.ChannelKind;
|
import org.openhab.core.thing.type.ChannelKind;
|
||||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
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) {
|
public boolean isValid(@NonNull List<@NonNull String> errors, @NonNull List<@NonNull String> warnings) {
|
||||||
boolean ok = true;
|
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) {
|
if (type != null) {
|
||||||
try {
|
try {
|
||||||
new ChannelTypeUID("dummy", type);
|
new ChannelTypeUID("dummy", type);
|
||||||
|
|||||||
+10
@@ -19,6 +19,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.YamlElement;
|
||||||
import org.openhab.core.model.yaml.YamlElementName;
|
import org.openhab.core.model.yaml.YamlElementName;
|
||||||
import org.openhab.core.model.yaml.internal.util.YamlElementUtils;
|
import org.openhab.core.model.yaml.internal.util.YamlElementUtils;
|
||||||
@@ -92,6 +93,15 @@ public class YamlThingDTO implements YamlElement, Cloneable {
|
|||||||
ok = false;
|
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) {
|
if (channels != null) {
|
||||||
for (Map.Entry<@NonNull String, @NonNull YamlChannelDTO> entry : channels.entrySet()) {
|
for (Map.Entry<@NonNull String, @NonNull YamlChannelDTO> entry : channels.entrySet()) {
|
||||||
String channelId = entry.getKey();
|
String channelId = entry.getKey();
|
||||||
|
|||||||
+41
-36
@@ -350,49 +350,54 @@ public class YamlThingProvider extends AbstractProvider<Thing>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable Thing mapThing(YamlThingDTO thingDto) {
|
private @Nullable Thing mapThing(YamlThingDTO thingDto) {
|
||||||
ThingUID thingUID = new ThingUID(thingDto.uid);
|
try {
|
||||||
String[] segments = thingUID.getAsString().split(AbstractUID.SEPARATOR);
|
ThingUID thingUID = new ThingUID(thingDto.uid);
|
||||||
ThingTypeUID thingTypeUID = new ThingTypeUID(thingUID.getBindingId(), segments[1]);
|
String[] segments = thingUID.getAsString().split(AbstractUID.SEPARATOR);
|
||||||
|
ThingTypeUID thingTypeUID = new ThingTypeUID(thingUID.getBindingId(), segments[1]);
|
||||||
|
|
||||||
ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID, localeProvider.getLocale());
|
ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID, localeProvider.getLocale());
|
||||||
ThingUID bridgeUID = thingDto.bridge != null ? new ThingUID(thingDto.bridge) : null;
|
ThingUID bridgeUID = thingDto.bridge != null ? new ThingUID(thingDto.bridge) : null;
|
||||||
Configuration configuration = new Configuration(thingDto.config);
|
Configuration configuration = new Configuration(thingDto.config);
|
||||||
|
|
||||||
ThingBuilder thingBuilder = thingDto.isBridge() ? BridgeBuilder.create(thingTypeUID, thingUID)
|
ThingBuilder thingBuilder = thingDto.isBridge() ? BridgeBuilder.create(thingTypeUID, thingUID)
|
||||||
: ThingBuilder.create(thingTypeUID, thingUID);
|
: ThingBuilder.create(thingTypeUID, thingUID);
|
||||||
thingBuilder
|
thingBuilder.withLabel(
|
||||||
.withLabel(thingDto.label != null ? thingDto.label : (thingType != null ? thingType.getLabel() : null));
|
thingDto.label != null ? thingDto.label : (thingType != null ? thingType.getLabel() : null));
|
||||||
thingBuilder.withLocation(thingDto.location);
|
thingBuilder.withLocation(thingDto.location);
|
||||||
thingBuilder.withBridge(bridgeUID);
|
thingBuilder.withBridge(bridgeUID);
|
||||||
thingBuilder.withConfiguration(configuration);
|
thingBuilder.withConfiguration(configuration);
|
||||||
|
|
||||||
List<Channel> channels = createChannels(thingTypeUID, thingUID,
|
List<Channel> channels = createChannels(thingTypeUID, thingUID,
|
||||||
thingDto.channels != null ? thingDto.channels : Map.of(),
|
thingDto.channels != null ? thingDto.channels : Map.of(),
|
||||||
thingType != null ? thingType.getChannelDefinitions() : List.of());
|
thingType != null ? thingType.getChannelDefinitions() : List.of());
|
||||||
thingBuilder.withChannels(channels);
|
thingBuilder.withChannels(channels);
|
||||||
|
|
||||||
Thing thing = thingBuilder.build();
|
Thing thing = thingBuilder.build();
|
||||||
|
|
||||||
Thing thingFromHandler = null;
|
Thing thingFromHandler = null;
|
||||||
ThingHandlerFactory handlerFactory = thingHandlerFactories.stream()
|
ThingHandlerFactory handlerFactory = thingHandlerFactories.stream()
|
||||||
.filter(thf -> isThingHandlerFactoryReady(thf) && thf.supportsThingType(thingTypeUID)).findFirst()
|
.filter(thf -> isThingHandlerFactoryReady(thf) && thf.supportsThingType(thingTypeUID)).findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (handlerFactory != null) {
|
if (handlerFactory != null) {
|
||||||
thingFromHandler = handlerFactory.createThing(thingTypeUID, configuration, thingUID, bridgeUID);
|
thingFromHandler = handlerFactory.createThing(thingTypeUID, configuration, thingUID, bridgeUID);
|
||||||
if (thingFromHandler != null) {
|
if (thingFromHandler != null) {
|
||||||
mergeThing(thingFromHandler, thing);
|
mergeThing(thingFromHandler, thing);
|
||||||
logger.debug("Successfully loaded thing \'{}\'", thingUID);
|
logger.debug("Successfully loaded thing \'{}\'", thingUID);
|
||||||
} else {
|
} else {
|
||||||
// Possible cause: Asynchronous loading of the XML files
|
// Possible cause: Asynchronous loading of the XML files
|
||||||
// Add the data to the queue in order to retry it later
|
// Add the data to the queue in order to retry it later
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"ThingHandlerFactory \'{}\' claimed it can handle \'{}\' type but actually did not. Queued for later refresh.",
|
"ThingHandlerFactory \'{}\' claimed it can handle \'{}\' type but actually did not. Queued for later refresh.",
|
||||||
handlerFactory.getClass().getSimpleName(), thingTypeUID);
|
handlerFactory.getClass().getSimpleName(), thingTypeUID);
|
||||||
queueRetryThingCreation(handlerFactory, thingTypeUID, configuration, thingUID, bridgeUID);
|
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,
|
private List<Channel> createChannels(ThingTypeUID thingTypeUID, ThingUID thingUID,
|
||||||
|
|||||||
Reference in New Issue
Block a user