Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throwing own exception in method causes "InvocationTargetRuntimeException" #32

Open
sherter opened this issue Jul 9, 2014 · 7 comments

Comments

@sherter
Copy link

sherter commented Jul 9, 2014

When I throw an exception in a method that gets invoked by CliFactory.parseArgumentsUsingInstance() I get a InvocationTargetRuntimeException in the first place rather than my own exception.

I don't know if there are reasons against it, but I would expect to receive my own exception. That way I could do some argument validation in the methods and throw exceptions respectively.

@lexicalscope
Copy link
Owner

Interesting. The reason this is happening is due to the methods being
called via reflection, where I wrap all exceptions thrown by the underlying
method into InvocationTargetRuntimeException. Your original exception can
be obtained by InvocationTargetRuntimeException.
getExceptionThrownByInvocationTarget.

I think though, having JewelCli propagate the original exception instead
might be a good idea, it should be possibly to change the JewelCli
implementation to do that, by extracting the original exception and
re-throwing from in the relevant place. Although the change will have to
wait a while until I have time to do it (unless someone else wants to do it
and send me a pull request).

On Wed, Jul 9, 2014 at 7:54 PM, Simon Herter [email protected]
wrote:

When I throw an exception in a method that gets invoked by
CliFactory.parseArgumentsUsingInstance() I get a
InvocationTargetRuntimeException in the first place rather than my own
exception.

I don't know if there are reasons against it, but I would expect to
receive my own exception. That way I could do some argument validation in
the methods and throw exceptions respectively.


Reply to this email directly or view it on GitHub
#32.

@sherter
Copy link
Author

sherter commented Jul 9, 2014

I currently use the workaround you describe.

InvocationTargetRuntimeException is thrown somewhere in the package com.lexicalscope.jewelcli.internal. However, this seems to be closed source, so there is not much I can do...

Exception in thread "main" com.lexicalscope.jewelcli.internal.fluentreflection.$InvocationTargetRuntimeException: Exception while invoking public void com.github.sherter.keygraphsim.CommandLineOptions.setLkh(java.util.List)
    at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.invokeMethod(FluentMethodImpl.java:121)
    at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.callRaw(FluentMethodImpl.java:106)
    at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.call(FluentMethodImpl.java:86)
    at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.setValueOnOptions(InstanceArgumentPresentingStrategy.java:64)
    at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.presentArguments(InstanceArgumentPresentingStrategy.java:44)
    at com.lexicalscope.jewel.cli.ArgumentPresenterImpl.presentArguments(ArgumentPresenterImpl.java:63)
    at com.lexicalscope.jewel.cli.AbstractCliImpl.parseArguments(AbstractCliImpl.java:42)
    at com.lexicalscope.jewel.cli.CliFactory.parseArgumentsUsingInstance(CliFactory.java:87)

@lexicalscope
Copy link
Owner

Its not closed source, its a copy of the classes from here, which are
renamed automatically as part of the jewelcli build process.
https://github.com/lexicalscope/fluent-reflection

I think perhaps though, it would prefer to unwrap and re-throw the
exception in InstanceArgumentPresentingStrategy.setValueOnOptions as this
should give a cleaner stack trace (without all the reflection stuff).

On Thu, Jul 10, 2014 at 12:31 AM, Simon Herter [email protected]
wrote:

I currently use the workaround you describe.

InvocationTargetRuntimeException is thrown somewhere in the package
com.lexicalscope.jewelcli.internal. However, this seems to be closed
source, so there is not much I can do...

Exception in thread "main" com.lexicalscope.jewelcli.internal.fluentreflection.$InvocationTargetRuntimeException: Exception while invoking public void com.github.sherter.keygraphsim.CommandLineOptions.setLkh(java.util.List)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.invokeMethod(FluentMethodImpl.java:121)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.callRaw(FluentMethodImpl.java:106)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.call(FluentMethodImpl.java:86)
at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.setValueOnOptions(InstanceArgumentPresentingStrategy.java:64)
at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.presentArguments(InstanceArgumentPresentingStrategy.java:44)
at com.lexicalscope.jewel.cli.ArgumentPresenterImpl.presentArguments(ArgumentPresenterImpl.java:63)
at com.lexicalscope.jewel.cli.AbstractCliImpl.parseArguments(AbstractCliImpl.java:42)
at com.lexicalscope.jewel.cli.CliFactory.parseArgumentsUsingInstance(CliFactory.java:87)


Reply to this email directly or view it on GitHub
#32 (comment)
.

@lexicalscope
Copy link
Owner

There is, though, the question of what to do about the order the methods
are called in / the possibility of multiple exceptions. Perhaps an even
better solution would be to collect all the exceptions up into a single
ArgumentValidationException and throw that instead...?

On Thu, Jul 10, 2014 at 8:00 AM, Tim Wood [email protected] wrote:

Its not closed source, its a copy of the classes from here, which are
renamed automatically as part of the jewelcli build process.
https://github.com/lexicalscope/fluent-reflection

I think perhaps though, it would prefer to unwrap and re-throw the
exception in InstanceArgumentPresentingStrategy.setValueOnOptions as this
should give a cleaner stack trace (without all the reflection stuff).

On Thu, Jul 10, 2014 at 12:31 AM, Simon Herter [email protected]
wrote:

I currently use the workaround you describe.

InvocationTargetRuntimeException is thrown somewhere in the package
com.lexicalscope.jewelcli.internal. However, this seems to be closed
source, so there is not much I can do...

Exception in thread "main" com.lexicalscope.jewelcli.internal.fluentreflection.$InvocationTargetRuntimeException: Exception while invoking public void com.github.sherter.keygraphsim.CommandLineOptions.setLkh(java.util.List)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.invokeMethod(FluentMethodImpl.java:121)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.callRaw(FluentMethodImpl.java:106)
at com.lexicalscope.jewelcli.internal.fluentreflection.$FluentMethodImpl.call(FluentMethodImpl.java:86)
at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.setValueOnOptions(InstanceArgumentPresentingStrategy.java:64)
at com.lexicalscope.jewel.cli.InstanceArgumentPresentingStrategy.presentArguments(InstanceArgumentPresentingStrategy.java:44)
at com.lexicalscope.jewel.cli.ArgumentPresenterImpl.presentArguments(ArgumentPresenterImpl.java:63)
at com.lexicalscope.jewel.cli.AbstractCliImpl.parseArguments(AbstractCliImpl.java:42)
at com.lexicalscope.jewel.cli.CliFactory.parseArgumentsUsingInstance(CliFactory.java:87)


Reply to this email directly or view it on GitHub
#32 (comment)
.

@sherter
Copy link
Author

sherter commented Jul 10, 2014

I don't think collecting all exceptions and then throw ArgumentValidationException instead is how exceptions in general should work. The client also looses the flexibility to throw and cache other exceptions. As a programmer, I would expect to receive the exact exception I have thrown in a setter method as soon as the error occurs, no matter in which order the setter methods are called. However, I understand your point if you wan't to print all errors at once rather than let the user try again and again.

What I'm not sure about is if only runtime exceptions should be allowed or checked exceptions as well. Allowing checked exceptions would maybe pollute the client code a bit, but it is easily possible that you want to have some file system checks, for example, for an option that represents a file.

@sherter
Copy link
Author

sherter commented Jul 11, 2014

I think perhaps though, it would prefer to unwrap and re-throw the
exception in InstanceArgumentPresentingStrategy.setValueOnOptions as this
should give a cleaner stack trace (without all the reflection stuff).

I don't see how this can help to clean up the stack trace of the original exception, since the setter method will always be called by reflect.Method.invoke.

orsonjones pushed a commit to orsonjones/jewelcli that referenced this issue Apr 23, 2015
@orsonjones
Copy link

I just stumbled across this and handling them as an ArgumentValidationException worked well enough for me. Returns useful error text such as:

Unexpected error (Date 1/1/20155 is out of bounds): --begin-date -b value : Begin Date. (M/d/yyyy)
Unexpected error (Date 5/1/20155 is out of bounds): --end-date -e value : End Date. (M/d/yyyy)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants