Skip to content

Commit

Permalink
Swallow exceptions when calling toString on configProxy
Browse files Browse the repository at this point in the history
  • Loading branch information
akang31 committed Feb 13, 2025
1 parent 9ca8b2f commit 99efa7e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ interface Subscription {
@Override
T get();

/**
* Return the most recent value of the property, swallowing any exceptions that occur.
*
* @return Most recent value for the property
*/
default T getSwallowErrors() {
return get();
}

/**
* Add a listener that will be called whenever the property value changes.
* @implNote Implementors of this interface MUST override this method or {@link #subscribe(Consumer)}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ protected interface PropertyValueGetter<T> {
* Invoke the method with the provided arguments
*/
T invoke(Object[] args);

default T invokeSwallowErrors(Object[] args) {
return invoke(args);
}
}

/**
Expand Down Expand Up @@ -488,9 +492,18 @@ protected <T> PropertyValueGetter<T> createInterfaceProperty(String propName, fi
protected <T> PropertyValueGetter<T> createScalarProperty(final Type type, final String propName, Function<Object[], T> defaultValueSupplier) {
LOG.debug("Creating scalar property `{}` for type `{}`", propName, type.getClass());
final Property<T> prop = propertyRepository.get(propName, type);
return args -> {
T value = prop.get();
return value != null ? value : defaultValueSupplier.apply(null);
return new PropertyValueGetter<T>() {
@Override
public T invoke(Object[] args) {
T value = prop.get();
return value != null ? value : defaultValueSupplier.apply(null);
}

@Override
public T invokeSwallowErrors(Object[] args) {
T value = prop.getSwallowErrors();
return value != null ? value : defaultValueSupplier.apply(null);
}
};
}

Expand Down Expand Up @@ -611,7 +624,7 @@ private String toNameAndValue(Map.Entry<Method, PropertyValueGetter<?>> entry) {
try {
// This call should fail for parameterized properties, because the PropertyValueGetter has a non-empty
// argument list. Fortunately, the implementation there cooperates with us and returns a null instead :-)
propertyValue = entry.getValue().invoke(null);
propertyValue = entry.getValue().invokeSwallowErrors(null);
} catch (Exception e) {
// Just in case
propertyValue = e.getMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ public PropertyImpl(KeyAndType<T> keyAndType, Supplier<T> supplier) {
*/
@Override
public T get() {
return internalGet(false);
}

@Override
public T getSwallowErrors() {
return internalGet(true);
}

private T internalGet(boolean swallowErrors) {
int currentMasterVersion = masterVersion.get();
CachedValue<T> currentCachedValue = this.cachedValue;

Expand All @@ -192,10 +201,12 @@ public T get() {
newValue = new CachedValue<>(supplier.get(), currentMasterVersion);

} catch (RuntimeException e) {
// Oh, no, something went wrong while trying to get the new value. Log the error and return null.
// Upstream users may return that null unchanged or substitute it by a defaultValue.
// We leave the cache unchanged, which means the next caller will try again.
LOG.error("Unable to update value for property '{}'", keyAndType.key, e);
if (!swallowErrors) {
// Oh, no, something went wrong while trying to get the new value. Log the error and return null.
// Upstream users may return that null unchanged or substitute it by a defaultValue.
// We leave the cache unchanged, which means the next caller will try again.
LOG.error("Unable to update value for property '{}'", keyAndType.key, e);
}
return null;
}

Expand Down

0 comments on commit 99efa7e

Please sign in to comment.