-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Stop returning "es." internal exception headers as http response headers #22703
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
Stop returning "es." internal exception headers as http response headers #22703
Conversation
3817f0d
to
2bc7547
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @javanna, I think this is heading in the right direction. I left some minor comments but we still need to figure out what to do with the TODOs :)
I do like the move of internal headers es.* to exception metadata and I share your concerns about serializing back a parsed exception... but that shouldn't happen, neither in core nor in the high level rest client.
For a long term, I think we should also drop the metadataToXcontent() method which can lead to name conflicts in the rendered xcontent and also adds confusion if we add a metadata class attribute.
} | ||
|
||
/** | ||
* Adds a new header with the given key. | ||
* This method will replace existing header if a header with the same key already exists | ||
*/ | ||
public void addHeader(String key, List<String> value) { | ||
//we need to enforce this otherwise bw comp doesn't work properly, as "es." was the previous criteria to split headers in two sets | ||
if (key.startsWith("es.")) { | ||
throw new IllegalArgumentException("exception headers must not start with [es.], found [" + key + "] instead"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe remove "instead" from the exception message?
@@ -410,6 +470,8 @@ public static ElasticsearchException fromXContent(XContentParser parser) throws | |||
|
|||
String type = null, reason = null, stack = null; | |||
ElasticsearchException cause = null; | |||
Map<String, List<String>> metadata = new HashMap<>(); | |||
//TODO should this be a Map<String, List<String>> instead? | |||
Map<String, Object> headers = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I changed it in #22675
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I will remove the TODO then
// Everything else is considered as a header | ||
headers.put(currentFieldName, parser.text()); | ||
//TODO here we need to parse multiple values | ||
metadata.put(currentFieldName, Collections.singletonList(parser.text())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's OK here because the token is a value, not an array. But later in the loop we need to take care of arrays.
I think we can already do it for values and just ignore objects for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we testing this somewhere?
} | ||
|
||
public void testWithHeaders() throws Exception { | ||
RestRequest request = new FakeRestRequest(); | ||
RestChannel channel = randomBoolean() ? new DetailedExceptionRestChannel(request) : new SimpleExceptionRestChannel(request); | ||
|
||
BytesRestResponse response = new BytesRestResponse(channel, new WithHeadersException()); | ||
assertEquals(2, response.getHeaders().size()); | ||
assertThat(response.getHeaders().get("n1"), notNullValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line is duplicated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
that's correct, I think that the problem is that those additional fields are printed at the same level as the metadata (previous es. headers). They should rather be in a different object that only subclasses can write, but that is a breaking change. That said I am not sure how many clients are able to parse our exceptions entirely given how difficult we made it for them :) |
@s1monw mind having a look too? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…Exception and stop returning them as response headers Closes elastic#17593
…ptionTests or ExceptionSerializationTests
17ab7eb
to
95b9979
Compare
95b9979
to
ea0ee3b
Compare
Move "es." internal headers to separate metadata set in
ElasticsearchException
and stop returning them as response headers. These headers are printed out as part of the response body already, they weren't meant to be sent back as response headers too. They were introduced to prevent having to add custom exceptions to our codebase whenever we need to throw an exception that has to hold some additional metadata thatElasticsearchException
doesn't support out of the box. The header notion stays inElasticsearchException
but only for what actually needs to be returned as response header (no "es." prefix).Also removed
ESExceptionTests
and moved its tests underElasticsearchExceptionTests
orExceptionSerializationTests
Closes #17593