Skip to content

Commit cf9aaee

Browse files
committed
small refactoring
1 parent 068cc28 commit cf9aaee

File tree

4 files changed

+47
-19
lines changed

4 files changed

+47
-19
lines changed

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerAutoConfiguration.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,6 @@ public GrpcServiceDiscoverer defaultGrpcServiceDiscoverer() {
108108
return new AnnotationGrpcServiceDiscoverer();
109109
}
110110

111-
// TODO eventually insert @Conditional
112-
113111
@ConditionalOnMissingBean
114112
@Bean
115113
public HealthStatusManager healthStatusManager() {

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/service/exceptionhandling/GrpcExceptionAspect.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@
3232
import org.springframework.stereotype.Component;
3333

3434
import io.grpc.stub.StreamObserver;
35-
import lombok.RequiredArgsConstructor;
3635
import lombok.extern.slf4j.Slf4j;
3736

3837
/**
39-
* Exception handling for thrown {@link RuntimeException} inside gRPC service classes, which implements
40-
* {@link io.grpc.BindableService}.
38+
* Exception handling for thrown {@link RuntimeException} inside annotated CLasses with
39+
* {@link net.devh.boot.grpc.server.service.GrpcService @GrpcService}, which implement {@link io.grpc.BindableService}.
40+
* <p>
41+
* After calling the mapped Methods to the corresponding Exception, the returned {@link Throwable} is beeing send to the
42+
* {@link io.grpc.stub.StreamObserver#onError(Throwable)}.
4143
*
4244
* TODO...
4345
*
@@ -46,16 +48,19 @@
4648
@Slf4j
4749
@Aspect
4850
@Component
49-
@RequiredArgsConstructor
5051
@ConditionalOnBean(annotation = GrpcServiceAdvice.class)
5152
public class GrpcExceptionAspect {
5253

53-
private final GrpcExceptionHandlerMethodResolver exceptionHandlerMethodResolver;
54+
private final GrpcExceptionHandlerMethodResolver grpcExceptionHandlerMethodResolver;
5455

5556
private Throwable exception;
5657
private Method mappedMethod;
5758
private Object instanceOfMappedMethod;
5859

60+
public GrpcExceptionAspect(final GrpcExceptionHandlerMethodResolver grpcExceptionHandlerMethodResolver) {
61+
this.grpcExceptionHandlerMethodResolver = grpcExceptionHandlerMethodResolver;
62+
}
63+
5964

6065
@Pointcut("within(@net.devh.boot.grpc.server.service.GrpcService *)")
6166
void grpcServiceAnnotatedPointcut() {}
@@ -67,9 +72,12 @@ void implementedBindableServicePointcut() {}
6772
pointcut = "grpcServiceAnnotatedPointcut() && implementedBindableServicePointcut()",
6873
throwing = "exception")
6974
public <E extends Throwable> void handleExceptionInsideGrpcService(JoinPoint joinPoint, E exception) {
70-
log.error("Runtimeexception caught during gRPC service execution: ", exception);
75+
log.error("Exception caught during gRPC service execution: ", exception);
7176
this.exception = exception;
7277

78+
if (!grpcExceptionHandlerMethodResolver.isMethodMappedForException(exception.getClass())) {
79+
return;
80+
}
7381
extractNecessaryInformation();
7482
Throwable throwable = invokeMappedMethodSafely();
7583
closeStreamObserverOnError(joinPoint.getArgs(), throwable);
@@ -80,7 +88,7 @@ private void extractNecessaryInformation() {
8088
final Class<? extends Throwable> exceptionClass = exception.getClass();
8189

8290
Entry<Object, Method> methodWithInstance =
83-
exceptionHandlerMethodResolver.resolveMethodWithInstance(exceptionClass);
91+
grpcExceptionHandlerMethodResolver.resolveMethodWithInstance(exceptionClass);
8492
mappedMethod =
8593
Optional.of(methodWithInstance)
8694
.map(Entry::getValue)
@@ -99,7 +107,7 @@ private Throwable invokeMappedMethodSafely() {
99107
Object statusThrowable = mappedMethod.invoke(instanceOfMappedMethod, instancedParams);
100108
return castToThrowable(statusThrowable);
101109
} catch (InvocationTargetException | IllegalAccessException e) {
102-
throw new IllegalStateException("No mapped instance found for Exception " + exception);
110+
throw new MethodExecutionException("Error during mapped exception method execution: ", e.getCause());
103111
}
104112
}
105113

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/service/exceptionhandling/GrpcExceptionHandlerMethodResolver.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Arrays;
2323
import java.util.HashMap;
2424
import java.util.Map;
25+
import java.util.Optional;
2526
import java.util.Set;
2627
import java.util.function.Function;
2728
import java.util.stream.Collectors;
@@ -30,10 +31,9 @@
3031
import org.springframework.beans.factory.InitializingBean;
3132
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3233
import org.springframework.context.ApplicationContext;
33-
import org.springframework.context.annotation.Configuration;
34+
import org.springframework.stereotype.Component;
3435
import org.springframework.util.Assert;
3536

36-
import lombok.RequiredArgsConstructor;
3737
import lombok.extern.slf4j.Slf4j;
3838

3939
/**
@@ -42,19 +42,21 @@
4242
* @author Andjelko ([email protected])
4343
*/
4444
@Slf4j
45-
@Configuration
46-
@RequiredArgsConstructor
45+
@Component
4746
@ConditionalOnBean(annotation = GrpcServiceAdvice.class)
48-
public class GrpcExceptionHandlerMethodResolver implements InitializingBean {
49-
50-
// TODO remove lombok
47+
class GrpcExceptionHandlerMethodResolver implements InitializingBean {
5148

5249
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
5350
private final ApplicationContext applicationContext;
5451

5552
private Class<? extends Throwable>[] annotatedExceptions;
5653
private Map<String, Object> annotatedBeans;
5754

55+
56+
GrpcExceptionHandlerMethodResolver(final ApplicationContext applicationContext) {
57+
this.applicationContext = applicationContext;
58+
}
59+
5860
@Override
5961
public void afterPropertiesSet() throws Exception {
6062
Set<Class<?>> annotatedClasses = findAllAnnotatedClasses();
@@ -100,6 +102,7 @@ private Class<? extends Throwable>[] checkForExceptionType(Class<?>[] methodPara
100102
throw new IllegalStateException("Annotated Class is not of Type Throwable: " + methodParamType);
101103
}
102104
}
105+
// safe to call, prior to the check above
103106
@SuppressWarnings("unchecked")
104107
Class<? extends Throwable>[] paramExceptionTypes = (Class<? extends Throwable>[]) methodParamTypes;
105108
return paramExceptionTypes;
@@ -132,12 +135,17 @@ private void addExceptionMapping(Class<? extends Throwable> exceptionType, Metho
132135
}
133136
}
134137

138+
<E extends Throwable> boolean isMethodMappedForException(Class<E> exception) {
139+
return mappedMethods.get(exception) != null;
140+
}
141+
142+
Map.Entry<Object, Method> resolveMethodWithInstance(Class<? extends Throwable> exceptionType) {
135143

136-
public Map.Entry<Object, Method> resolveMethodWithInstance(Class<? extends Throwable> exceptionType) {
137144
Method value = mappedMethods.get(exceptionType);
145+
Class<?> methodClass = Optional.ofNullable(value).map(Method::getDeclaringClass).orElse(null);
138146
Object key = annotatedBeans.values()
139147
.stream()
140-
.filter(obj -> obj.getClass().equals(value.getDeclaringClass()))
148+
.filter(obj -> obj.getClass().equals(methodClass))
141149
.findFirst()
142150
.orElse(null);
143151

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
package net.devh.boot.grpc.server.service.exceptionhandling;
3+
4+
/**
5+
* TODO..
6+
*
7+
* @author Andjelko ([email protected])
8+
*/
9+
class MethodExecutionException extends RuntimeException {
10+
11+
MethodExecutionException(String msg, Throwable e) {
12+
super(msg, e);
13+
}
14+
}

0 commit comments

Comments
 (0)