ctubbsii opened a new issue, #6061:
URL: https://github.com/apache/accumulo/issues/6061
## The problem:
* Generated Thrift interfaces always add `TException` as an allowed
exception to every method, in addition to any user-defined Thrift exception
types.
* User-defined Thrift exception types extend `TException`, so they do not
result in a compile error if thrown from handler code that implements the
interface.
* The user-defined Thrift exception types that are declared in the IDL (aka,
the ones that are *supposed* to be thrown from user code) have different
handling behavior than ones that are not expected to be thrown; the expected
ones get returned to the client and can be handled with catch blocks; the
unexpected ones cause a `TApplicationException` to be returned instead.
This combination of facts leads to the possibility of having mismatched
exceptions thrown from RPC handler code that is not properly handled by calling
client code.
For example, consider the IDL:
```
i64 doTask(1:string name) throws (1:BadTaskNameException ex)
string waitForTask(1:i64 taskId) throws (1:InvalidTaskException ex)
```
Since the generated code includes `TException`, and since both of the
exceptions above are `TException`s, one could write the following valid Java
code:
```java
@Override
public long doTask(String name) throws BadTaskNameException, TException {
if (!name.startsWith("task")) {
throw new InvalidTaskException(); // this shouldn't be thrown, but it is
allowed because it is a TException
}
// ... do more work here ...
}
```
Just as bad, the `throws TException` could be replaced with a more narrow
sub-type of `TException`, and say `throws InvalidTaskException`. The compiler
would allow this, because you can always narrow the exception type in an
implementing class or subclass, but this isn't any more correct, because it
won't have correct behavior. The only allowed user-exception for the `doTask`
method is `BadTaskNameException`. No other `TException`s should be thrown,
because they will not be returned to the client, and will instead result in a
`TApplicationException`.
This problem definitely exists in Accumulo code in at least one place,
caused by #3177 and an attempted fix in #6048.
## What to do
All Accumulo RPC handler methods (that is, any non-generated method that
implements a Thrift-generated `Iface` interface) should be audited to ensure
that they:
1. Do *NOT* declare `throws TException`, because that allows invalid
exception types to fall through unnoticed.
2. Do *NOT* declare `throws` for any `TException` subclass that is not
defined as a thrown exception type in the corresponding `*.thrift` IDL, because
that results in a mismatch between what was declared as allowed and what is
being thrown, with incorrect behavior.
3. (Optional) Contain all the exceptions declared in the IDL (even those
unused), to ensure documentation of which ones are allowed. It's generally okay
to throw fewer exceptions than those declared on the interface, but it might be
better to keep them in for the RPC methods if other QA tooling doesn't
complain, just as documentation.
Any existing violation of these needs to be rewritten to wrap the exception
in one of the declared allowable exception types or, if `TApplicationException`
is acceptable for that scenario, be wrapped in an appropriate subclass of
`RuntimeException`.
If we can find some way to write a unit test to automate these checks, that
might be very useful. The test may be able to search through a list of
handlers, then look at the exceptions declared on the interface, exclude the
`TException`, and fail if the implementing method declares a thrown exception
that is not in that set.
Related: For the code changes in #3177, several related methods were changed
to throw a new `ThriftPropertyException` type. However, not all similar methods
were modified. Some namespace and system methods were unchanged. These methods
should also be audited to ensure that they are behaving correctly. Even if they
don't violate the RPC exception checks listed above, they may not be written to
handle the exceptional property validation checks in a way that is consistent
with their related methods.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]