// 4) Entries may have new values.
if (async.isReady()) {
value = async.getValue();
} else {
ProviderResult result = null;
Throwable throwable = null;
boolean failed = true;
try {
// Get the entry, this will return null if the entry is marked
// as being uncacheable.
CacheEntry entry = async.getEntry();
// Get the provider to retrieve the object. It is given the
// whole entry so that it can perform revalidation of an
// existing entry if it has expired.
result = provider.retrieve(clock, key, entry);
if (result == null) {
throw new IllegalStateException("Result from provider is null");
}
// Request to the provider did not fail.
failed = false;
} catch (RuntimeException e) {
// Remember the exception so that it can be stored in the
// entry to indicate the original cause.
throwable = e;
// Rethrow the exceptions.
throw e;
} catch (Error e) {
// Remember the exception so that it can be stored in the
// entry to indicate the original cause.
throwable = e;
// Rethrow the exceptions.
throw e;
} finally {
if (failed) {
async.failed(throwable);
} else {
// the cache must be updated even if the result has a
// non-null throwable
value = async.update(result);
// if the result has a throwable, thow it wrapped inside a
// runtime exception
Throwable cause = result.getThrowable();
if (cause != null) {
// The entry has a throwable so throw a runtime
// exception, encapsulating the original throwable.
throw new ExtendedRuntimeException(
"Attempt to access " + key +