Class ExceptionInterceptor
- All Implemented Interfaces:
MethodInterceptor
When a method throws an exception that matches the @ExceptionCatch configuration, this interceptor catches it and returns a default value instead of propagating.
- Since:
- 6.2.0
- Author:
- wisdomme
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final SimpleContainerContainer used to resolve@ExceptionCatch(handler = "...")beans.private final List<ExceptionHandler> private static final Loggerprivate final AnnotationLookupCache<ExceptionCatch> Instance-scoped on purpose - see AnnotationLookupCache's class javadoc. -
Constructor Summary
ConstructorsConstructorDescriptionCreates an exception interceptor with no global handlers and no container.ExceptionInterceptor(List<ExceptionHandler> globalHandlers) Creates an exception interceptor with the given global handlers and no container.ExceptionInterceptor(List<ExceptionHandler> globalHandlers, SimpleContainer context) Creates an exception interceptor bound to a plugin's container, with its own unsharedAnnotationLookupCache.ExceptionInterceptor(List<ExceptionHandler> globalHandlers, SimpleContainer context, AnnotationLookupCache<ExceptionCatch> lookupCache) Creates an exception interceptor bound to a plugin's container, using a caller-suppliedAnnotationLookupCacheinstead of building its own. -
Method Summary
Modifier and TypeMethodDescriptionprivate static Class<?> beanClassOf(MethodInvocation invocation, Method method) The class the bean actually is, with any proxy layers unwrapped.private ObjectgetDefaultValue(Class<?> type) Gets the default value for a type.private ObjectgetEmptyValue(Class<?> type) Gets an empty value for collection/array/string types.private ObjecthandleCaughtException(Throwable e, MethodInvocation invocation, ExceptionCatch annotation) Handles a caught exception according to the annotation configuration.invoke(MethodInvocation invocation) Intercept the given method invocation.private ObjectparseDefaultValue(String expression, Class<?> returnType) Parses a default value expression into an actual value.private booleanshouldCatch(Throwable e, Class<? extends Throwable>[] types) Checks if the given exception should be caught based on the configured types.
-
Field Details
-
LOGGER
-
globalHandlers
-
lookupCache
Instance-scoped on purpose - see AnnotationLookupCache's class javadoc. -
context
Container used to resolve@ExceptionCatch(handler = "...")beans.Injected per plugin rather than read from a global static holder: each plugin has its own container, and a single static holder would make the last plugin to initialise win, sending every earlier plugin's handler lookup to the wrong container. See issue #190.
-
-
Constructor Details
-
ExceptionInterceptor
public ExceptionInterceptor()Creates an exception interceptor with no global handlers and no container. -
ExceptionInterceptor
Creates an exception interceptor with the given global handlers and no container.- Parameters:
globalHandlers- handlers to try for any exception
-
ExceptionInterceptor
Creates an exception interceptor bound to a plugin's container, with its own unsharedAnnotationLookupCache.A caller that also builds an
AopAdvisorfor@ExceptionCatchshould useExceptionInterceptor(List, SimpleContainer, AnnotationLookupCache)instead and inject one shared instance into both (D-38).PluginManager.wireAopis that caller; this constructor exists for standalone construction and for exercising this interceptor in isolation.- Parameters:
globalHandlers- handlers to try for any exceptioncontext- the container used to resolve named handlers, may be null
-
ExceptionInterceptor
public ExceptionInterceptor(List<ExceptionHandler> globalHandlers, SimpleContainer context, AnnotationLookupCache<ExceptionCatch> lookupCache) Creates an exception interceptor bound to a plugin's container, using a caller-suppliedAnnotationLookupCacheinstead of building its own.Sharing the cache does not change what this interceptor asks it:
invoke(com.ultikits.ultitools.aop.MethodInvocation)still resolves own-method, then class-level, then inherited-method, with class-level ranking between the other two - only the memoized answers are shared with whichever advisor was given the same instance (D-38).- Parameters:
globalHandlers- handlers to try for any exceptioncontext- the container used to resolve named handlers, may be nulllookupCache- the cache to use instead of constructing a new one
-
-
Method Details
-
invoke
Description copied from interface:MethodInterceptorIntercept the given method invocation.Implementations should call
MethodInvocation.proceed()to continue the interceptor chain or invoke the target method.- Specified by:
invokein interfaceMethodInterceptor- Parameters:
invocation- the method invocation context- Returns:
- the result of the method invocation
- Throws:
Throwable- if the interceptor or target method throws an exception
-
shouldCatch
Checks if the given exception should be caught based on the configured types. -
beanClassOf
The class the bean actually is, with any proxy layers unwrapped.Used for attribution only. Which class-level annotation governs a method is decided by
AopAdvisor.findClassLevelAnnotation(Method, Class), which anchors on the declaring class and never consults the target. Attribution wants the opposite: for an inherited method the declaring class is often a framework base, which tells an operator nothing about which concrete bean failed and makes ErrorReportCollector's fingerprint dedup collapse two different beans into one report. The declaring class remains the fallback for a null target - that branch is not proxy identity and is out of scope for this method's unwrap. See issue #309.Unwrapping itself delegates to
ProxyFactory.unwrap(Class): a proxy of a proxy already names the original target, so no hierarchy walk is needed here either.- Parameters:
invocation- the invocation in progressmethod- the method being intercepted- Returns:
- the bean class, never null
-
handleCaughtException
private Object handleCaughtException(Throwable e, MethodInvocation invocation, ExceptionCatch annotation) throws Throwable Handles a caught exception according to the annotation configuration.- Throws:
Throwable
-
parseDefaultValue
Parses a default value expression into an actual value. -
getDefaultValue
Gets the default value for a type. -
getEmptyValue
Gets an empty value for collection/array/string types.
-