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

HLRC: Fix strict setting exception handling #37247

Merged
merged 9 commits into from
Jan 30, 2019
Merged

Conversation

hub-cap
Copy link
Contributor

@hub-cap hub-cap commented Jan 9, 2019

The LLRC's exception handling for strict mode was previously throwing an
exception the HLRC assumed was an error response. This is not the case
if the result is valid in strict mode, as it will return the proper
response wrapped in an exception with warnings. This commit fixes the
HLRC such that it no longer spews if it encounters a strict LLRC
response.

Closes #37090

The LLRC's exception handling for strict mode was previously throwing an
exception the HLRC assumed was an error response. This is not the case
if the result is valid in strict mode, as it will return the proper
response wrapped in an exception with warnings. This commit fixes the
HLRC such that it no longer spews if it encounters a strict LLRC
response.

Closes elastic#37090
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-features

@hub-cap
Copy link
Contributor Author

hub-cap commented Jan 9, 2019

@elasticmachine please run gradle build tests 1


if (responseException instanceof WarningFailureException) {
elasticsearchException = new ElasticsearchStatusException("Warnings/Deprecations caused response to fail", restStatus,
responseException);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find using ElasticsearchStatusException almost as weird as using ResponseException. That is because such exceptions are meant for error status codes, while warnings can come back with any response.

I would prefer if we could have a separate catch for the warnings case, with a different exception that does not extend ResponseException. Maybe we could add a new exception to the low-level client that does not extend ResponseException, and let the high-level client bubble it up as-is? Not sure what I may be missing that prevents us from going down this route...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all we have to do for that is to make the new exception not extend ResponseException. It might have to extend RuntimeException so we don't break compilation. Which'd be fine with me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right Nik, probably we do not even need a catch for the new exception, just let it bubble up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason I used the existing ElasticsearchStatusException was because that is what was thrown before. If you take a look at https://github.com/elastic/elasticsearch/blob/master/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java#L1670, it is the method that sync/async both call when a ResponseException is thrown from the LLRC. Im not sure there is a ton of value wrapping either of these in ElasticsearchStatusException. I think removing this would be a breaking change tho?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and to @nik9000 point, if we just throw another exception, it works great for sync, but for async it throws the following

UncategorizedExecutionException[Failed execution
]; nested: ExecutionException[org.elasticsearch.client.DeprecationException

That said, ofc we can make it do whatever we want. Id still lean toward 1) doing nothing different and still throwing a ElasticsearchStatusException, or 2) unwrapping both the ResponseException and WarningFailureException and throwing them w/o the ElasticsearchStatusException (breaking?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that removing the ElasticsearchStatusException wrapped from the ResponseException thrown would be a bad breaking change.

I think that one has been around much longer, yeah. But i'm just going from memory. We could throw a special deprecation exception instead, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea this is what the code does as is, even with it being child of ResponseException, its just currently wrapped in a ElasticsearchStatusException as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javanna Id like your opinion on whether to break the current functionality, which is to always return an ElasticsearchStatusException unless its a random exception we dont know about. Ill gladly throw the WarningFailureException w/o wrapping it, just want to make sure thats the correct thing to do WRT compatibility. I think @nik9000 says he is ok with it, correct @nik9000 ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine throwing the WarningFailureException, unwrapped, not extending ElasticsearchStatusException.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine too with rethrowing WarningFailureException as-is.

@hub-cap
Copy link
Contributor Author

hub-cap commented Jan 23, 2019

@javanna @nik9000 Now we have a nice throw (see below) from the async code, with one caveat. The async code uses this from server which expects any exception to be either an ElasticsearchException or a RuntimeException. I decided to make WarningFailureException extend RuntimeException so it would not wrap it here.

org.elasticsearch.client.WarningFailureException: method [PUT], host [http://127.0.0.1:9200], URI [/index/type/id?timeout=1m], status line [HTTP/1.1 201 Created]
Warnings: [[types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).]
---
_index: "index"
_type: "type"
_id: "id"
_version: 1
result: "created"
_shards:
  total: 2
  successful: 1
  failed: 0
_seq_no: 0
_primary_term: 1

Id love another quick look.

@hub-cap
Copy link
Contributor Author

hub-cap commented Jan 23, 2019

@elasticmachine run elasticsearch-ci/1

Copy link
Member

@javanna javanna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -30,7 +30,7 @@
* Exception thrown when an elasticsearch node responds to a request with a status code that indicates an error.
* Holds the response that was returned.
*/
public final class ResponseException extends IOException {
public class ResponseException extends IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that these changes to ResponseException are no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh, good call!

// if the exception is not of type ElasticsearchException or RuntimeException it will be wrapped in a UncategorizedExecutionException
public class WarningFailureException extends RuntimeException {

private Response response;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it final?

@hub-cap hub-cap merged commit 2cbc688 into elastic:master Jan 30, 2019
jasontedor added a commit to dnhatn/elasticsearch that referenced this pull request Jan 30, 2019
* master:
  Expose retention leases in shard stats (elastic#37991)
  Make primary terms fields private in index shard (elastic#38036)
  ML: Add reason field in JobTaskState (elastic#38029)
  Log flush_stats and commit_stats in testMaybeFlush
  HLRC: Fix strict setting exception handling (elastic#37247)
  Test: Enable strict deprecation on all tests (elastic#36558)
  Removes typed calls from YAML REST tests (elastic#37611)
  Switch default time format for ingest from Joda to Java for v7 (elastic#37934)
  Remove deprecated Plugin#onModule extension points (elastic#37866)
  Geo: Fix Empty Geometry Collection Handling (elastic#37978)
@romseygeek
Copy link
Contributor

I think this is causing (non-reproducible) failures in FullClusterRestartIT, specifically here:

The test is anticipating a ResponseException, but it will now get a WarningFailureException instead and so won't catch it.

hub-cap added a commit to hub-cap/elasticsearch that referenced this pull request Jan 31, 2019
The LLRC's exception handling for strict mode was previously throwing an
exception the HLRC assumed was an error response. This is not the case
if the result is valid in strict mode, as it will return the proper
response wrapped in an exception with warnings. This commit fixes the
HLRC such that it no longer spews if it encounters a strict LLRC
response.

Closes elastic#37090
Relates elastic#37247
hub-cap added a commit that referenced this pull request Jan 31, 2019
The LLRC's exception handling for strict mode was previously throwing an
exception the HLRC assumed was an error response. This is not the case
if the result is valid in strict mode, as it will return the proper
response wrapped in an exception with warnings. This commit fixes the
HLRC such that it no longer spews if it encounters a strict LLRC
response.

Closes #37090
Relates #37247
dnhatn added a commit that referenced this pull request Feb 2, 2019
We now throw a WarningFailureException instead of ResponseException if
there's any warning in a response. This change leads to the failures of
testSnapshotRestore in the BWC builds for the last two days.

Relates #37247
@danielmitterdorfer danielmitterdorfer removed the :Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch label Feb 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deprecation warnings break the high-level client in strict mode
7 participants