ametiste-oss / ametiste-lambda-platform

1 stars 0 forks source link

SessionStatProxy doesn't unwrap InvocationTargetProxy exception #1

Open abliznyuk opened 8 years ago

abliznyuk commented 8 years ago

Method.invoke() wraps any execution exception with InvocationTargetException, as result undeclared Exception thrown. This causes that we have java.lang.reflect.UndeclaredThrowableException and don't catch expected (declared) exceptions.

Location: SessionStatProxy.java#L50

Example of processing in org.springframework.cglib.proxy.MethodProxy:

    public Object invoke(Object obj, Object[] args) throws Throwable {
        try {
            this.init();
            MethodProxy.FastClassInfo e = this.fastClassInfo;
            return e.f1.invoke(e.i1, obj, args);
        } catch (InvocationTargetException var5) {
            throw var5.getTargetException();
        } catch (IllegalArgumentException var6) {
            if(this.fastClassInfo.i1 < 0) {
                String var4 = String.valueOf(this.sig1);
                throw new IllegalArgumentException((new StringBuilder(18 + String.valueOf(var4).length())).append("Protected method: ").append(var4).toString());
            } else {
                throw var6;
            }
        }
    }
detsam commented 8 years ago

But Throwable is a superclass for each of other exception types. Are you sure that there the problem that is described, I guess there is something different. Could you attach any related stacktrace log please?

abliznyuk commented 8 years ago
java.lang.reflect.UndeclaredThrowableException
    at com.sun.proxy.$Proxy181.validate(Unknown Source)
    at org.ame.conv.image.thumb.gen.infrastructure.routine.task.GenerateBigPreviewThumbTask.generate(GenerateBigPreviewThumbTask.java:65)
    at sun.reflect.GeneratedMethodAccessor178.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.ametiste.routine.dsl.application.DynamicOperationFactory.lambda$createDynamicOperation$3(DynamicOperationFactory.java:59)
    at org.ametiste.routine.dsl.application.DynamicOperationFactory$$Lambda$177/1011882294.run(Unknown Source)
    at org.ametiste.routine.dsl.application.DynamicOperationExecutor.execOperation(DynamicOperationExecutor.java:17)
    at org.ametiste.routine.infrastructure.execution.local.LocalLineExecutionGateway.executeOperation(LocalLineExecutionGateway.java:72)
    at org.ametiste.routine.infrastructure.execution.local.LocalLineExecutionGateway$$FastClassBySpringCGLIB$$bb5f62bf.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at org.ametiste.metrics.aop.TimeableAspect.processTiming(TimeableAspect.java:72)
    at sun.reflect.GeneratedMethodAccessor152.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    at org.ametiste.routine.infrastructure.execution.local.LocalLineExecutionGateway$$EnhancerBySpringCGLIB$$6f886ebc.executeOperation(<generated>)
    at org.ametiste.routine.infrastructure.execution.local.LocalTaskExecutionGateway$$Lambda$134/528830068.accept(Unknown Source)
    at org.ametiste.routine.domain.task.ExecutionOrder.lambda$executionLines$0(ExecutionOrder.java:31)
    at org.ametiste.routine.domain.task.ExecutionOrder$$Lambda$135/702809783.accept(Unknown Source)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080)
    at org.ametiste.routine.domain.task.ExecutionOrder.executionLines(ExecutionOrder.java:30)
    at org.ametiste.routine.infrastructure.execution.local.LocalTaskExecutionGateway.lambda$startTaskExecution$0(LocalTaskExecutionGateway.java:63)
    at org.ametiste.routine.infrastructure.execution.local.LocalTaskExecutionGateway$$Lambda$121/1537880111.run(Unknown Source)
    at org.ametiste.routine.infrastructure.execution.local.BoundedExecutor.lambda$submitTask$0(BoundedExecutor.java:24)
    at org.ametiste.routine.infrastructure.execution.local.BoundedExecutor$$Lambda$123/568735712.run(Unknown Source)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor186.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.ametiste.laplatform.protocol.gateway.SessionStatProxy.invoke(SessionStatProxy.java:49)
    ... 41 more
Caused by: org.ame.conv.image.thumb.gen.domain.thumb.ThumbValidationException: Thumb file /data/d4700/thumbs/6354136/126532066/thumb_1600.jpg not exists
    at org.ame.conv.image.thumb.gen.infrastructure.thumb.FileExistsThumbValidator.validate(FileExistsThumbValidator.java:19)
    at org.ame.conv.image.thumb.gen.domain.thumb.CompositeThumbValidator.lambda$validate$0(CompositeThumbValidator.java:31)
    at org.ame.conv.image.thumb.gen.domain.thumb.CompositeThumbValidator$$Lambda$180/1065684109.accept(Unknown Source)
    at java.util.Arrays$ArrayList.forEach(Arrays.java:3880)
    at org.ame.conv.image.thumb.gen.domain.thumb.CompositeThumbValidator.validate(CompositeThumbValidator.java:31)
    at org.ame.conv.image.thumb.gen.infrastructure.routine.protocol.thumb.ImageThumbValidatorConnector.validate(ImageThumbValidatorConnector.java:25)
    ... 45 more
detsam commented 8 years ago

So, where the problem? Please describe a problem in terms of case/expectations/causes/effects. At the moment I can see FileExistsThumbValidator that is protocol that throwing the exception, not obvious yeah, but protocols can't raise any exception by the current contract. I guess, the problem is here - you expecting to get ThumbValidationException and get nothing, but is not a problem in the current implementation version, is a contract violation.

I can suggest to redesign FileExistsThumbValidator to have data type that defines validation results and return such object as a result of validator invocation. Or have callback object that can accept validation results.

In other hand, there is bunch of tasks to support fluent exception transitions via protocol's lifecycle ( yep, I want to enchant contract and want to enable ability to define reach interfaces ), so you can just suggest a solution. But...

In any way, exception as validation failure indicator is a bad choice at this concrete situation. Exception is a signal about something exceptional in the object's domain, failures are common for validation domain.