Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guava cache and preserving checked exceptions

Tags:

I'm refactoring some code to use guava Cache.

Initial code:

public Post getPost(Integer key) throws SQLException, IOException {     return PostsDB.findPostByID(key); } 

In order not to break something I need to preserve any thrown exception as is, without wrapping it.

Current solution appears somewhat ugly:

public Post getPost(final Integer key) throws SQLException, IOException {     try {         return cache.get(key, new Callable<Post>() {             @Override             public Post call() throws Exception {                 return PostsDB.findPostByID(key);             }         });     } catch (ExecutionException e) {         Throwable cause = e.getCause();         if (cause instanceof SQLException) {             throw (SQLException) cause;         } else if (cause instanceof IOException) {             throw (IOException) cause;         } else if (cause instanceof RuntimeException) {             throw (RuntimeException) cause;         } else if (cause instanceof Error) {             throw (Error) cause;         } else {             throw new IllegalStateException(e);         }     } } 

Is there any possible way to make it nicer?

like image 272
Vadzim Avatar asked Dec 27 '11 14:12

Vadzim


People also ask

What is a guava cache?

The Guava Cache is an incremental cache, in the sense that when you request an object from the cache, it checks to see if it already has the corresponding value for the supplied key. If it does, it simply returns it (assuming it hasn't expired).

Is guava in memory cache?

Guava provides a very powerful memory based caching mechanism by an interface LoadingCache<K,V>. Values are automatically loaded in the cache and it provides many utility methods useful for caching needs.

How does LoadingCache work?

Interface LoadingCache<K,V> A semi-persistent mapping from keys to values. Values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated. Implementations of this interface are expected to be thread-safe, and can be safely accessed by multiple concurrent threads.


1 Answers

Just after writing the question started thinking about utility method powered with generics. Then remembered something about Throwables. And yes, it's already there! )

It may also be necessary to handle UncheckedExecutionException or even ExecutionError.

So the solution is:

public Post getPost(final Integer key) throws SQLException, IOException {     try {         return cache.get(key, new Callable<Post>() {             @Override             public Post call() throws Exception {                 return PostsDB.findPostByID(key);             }         });     } catch (ExecutionException e) {         Throwables.propagateIfPossible(             e.getCause(), SQLException.class, IOException.class);         throw new IllegalStateException(e);     } catch (UncheckedExecutionException e) {         Throwables.throwIfUnchecked(e.getCause());         throw new IllegalStateException(e);     } } 

Very nice!

See also ThrowablesExplained, LoadingCache.getUnchecked and Why we deprecated Throwables.propagate.

like image 97
Vadzim Avatar answered Sep 28 '22 08:09

Vadzim