Reputation: 937
I am using Spring boot and hazelcast for my REST service for caching.
I am caching at service layer (API) using spring @Cachable annotation with custom key generator. Every thing works fine except when it throws RuntimeException from custom key generator function it is not handled by custom error class which I have added to handle error scenario.
The custom error class (CacheErrorHandler) that extends org.springframework.cache.annotation.CachingConfigurerSupport overrides all methods to handle GET,PUT,EVICT errors.
In my case I am expecting it to break into handleCacheGetError function if the custom customKeyGenerator throw RuntimeException.
Can any body point me what I am missing here or help to explain is the right way to handle caching error for cache (like HAZELCAST or REDIS etc) with spring annotation (i.e. using @Cachable).
As sample , here is what my API caching looks like
@Cacheable(cacheNames = "TestCache",keyGenerator = "customKeyGenerator")
public Response getAPIResponse(Integer param1){
...
}
Similarly , my cache configuration class which extends CachingConfigurerSupport, looks like this
@Configuration
public class CacheConfiguration extends CachingConfigurerSupport {
...
@Override
public CacheErrorHandler errorHandler() {
return new CustomHZCacheErrorHandler();
}
...
}
Here CustomHZCacheErrorHandler looks like
public class CustomHZCacheErrorHandler implements CacheErrorHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomHZCacheErrorHandler.class);
public CustomHZCacheErrorHandler() {
}
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
logger.warn("Error while getting cache " + cache.getName() + " for Key " + key);
}
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
logger.warn("Error while putting cache " + cache.getName() + " for Key " + key);
}
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
logger.warn("Error while evicting cache " + cache.getName() + " for Key " + key);
}
public void handleCacheClearError(RuntimeException exception, Cache cache) {
logger.warn("Error while clearing cache " + cache.getName());
}
}
Upvotes: 0
Views: 1360
Reputation: 3257
@NRA, according to Spring Doc, https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/interceptor/CacheErrorHandler.html, CacheErrorHandler
used only exceptions thrown by the cache provider, nothing else. Not for Key Generator or not even for the exceptions thrown by the annotated method.
For MVC Controller, Spring has an annotation to help you handle errors: @ErrorHandler
. You can find more details here: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
If not using MVC, you can define an Aspect
Bean & handle all errors for that method/class/package. The trick is, KeyGenerator
called using an interceptor, before the method, so you need to put an aspect to that KeyGenerator
class as well to catch it.
Please see this working example: https://gist.github.com/gokhanoner/026c2b90fe3a61b93626383a61932395
Note: I didn't test throwing exception from Cache provider side, you most probably need to define CacheErrorHandler
as well for that part.
Upvotes: 1