[savedObjects] fix error handling when Kibana index is missing#14141
[savedObjects] fix error handling when Kibana index is missing#14141spalger merged 34 commits intoelastic:masterfrom
Conversation
kimjoar
left a comment
There was a problem hiding this comment.
Just a couple nitpicks, but I'm good with merging as-is. LGTM
| } | ||
|
|
||
| // 404 might be because document is missing or index is missing, | ||
| // don't leak that implementation detail to the user |
There was a problem hiding this comment.
Would be great if we could add an explanation here. (Basically answering the question: Why don't we want to leak this to the user?)
We've got this same comment in multiple places. Not sure if we should add an explanation in one place and "link" there, but it feels like we should make it clear here, at least.
| .expect(200) | ||
| .then(resp => { | ||
| expect(resp.body).to.eql({ | ||
| saved_objects: [ |
There was a problem hiding this comment.
Would be 🎉 to have snapshot tests for these, but that's of course not possible yet
There was a problem hiding this comment.
These are basically snapshot tests, no? What would be different with a snapshot test?
There was a problem hiding this comment.
++ Yeah, it's basically the same (I just prefer working with snapshots over large objects, e.g. when changing code etc)
There was a problem hiding this comment.
Shit, I totally meant to delete my comment, thought it failed, and accidentally deleted yours 😿
| }); | ||
| }); | ||
|
|
||
| describe('unkown id', () => { |
| } | ||
|
|
||
| /** | ||
| * ## SavedObjectsClient errors |
There was a problem hiding this comment.
Alright, you asked for some docs @kjbekkelund :) I don't think it's bad to have some of these thought written down but let me know if you think I went overboard
There was a problem hiding this comment.
❤️ I like this! It gives tons of context and makes it way easier to understand why we do what we do.
| const indexNotFound = response.error && response.error.type === 'index_not_found_exception'; | ||
| if (docNotFound || indexNotFound) { | ||
| // see "404s from missing index" above | ||
| throw errors.createGenericNotFoundError(); |
There was a problem hiding this comment.
I also fixed the lib/errors module. Including a decorateNotFoundError contradicts the goal of not exposing where NotFound errors come from, so now it has a createGenericNotFoundError() that does the same thing these lines were doing.
|
@epixa any more feedback? |
| * by the decorators in `./lib/errors` | ||
| * | ||
| * Type 1 errors are inevitable, but since all expected/handle-able errors | ||
| * should be Type 2 the `isXYZError()` helpers exposed at `SavedObjectsClient.errors` |
There was a problem hiding this comment.
typo: is this a typo (double mentioning of SavedObjectsClient.errors)?
| * ### 404s from missing index | ||
| * | ||
| * From the perspective of application code and APIs the SavedObjectsClient is | ||
| * a black box that persists objects. One of the internal details that the client |
There was a problem hiding this comment.
question: just for my understanding, that the client has no control over - the client here is the consumer of SavedObjectsClient or the SavedObjectsClient itself?
There was a problem hiding this comment.
Yeah, I use client here to mean SavedObjectsClient and browser/user client. I'll more clearly distinguish those.
| * | ||
| * At the time of writing we are in the process of transitioning away from the | ||
| * operating assumption that the SavedObjects index is always available. Part of | ||
| * this transition is handling errors resulting from an index missing. These use |
There was a problem hiding this comment.
typo: these use to trigger --> these used to trigger?
| expect(error.output.payload).to.have.property('message', 'biz: foobar'); | ||
| it('Uses "Not Found" message', () => { | ||
| const error = createGenericNotFoundError(); | ||
| expect(error.output.payload).to.have.property('message', 'Not Found'); |
There was a problem hiding this comment.
question: there is no need to change anything here, just wondering why not to use to.be?
expect(error.output.payload.message).to.be('Not Found')There was a problem hiding this comment.
the error message shows the properties that do exist, that is all
| }); | ||
| await savedObjectsClient.delete('index-pattern', 'logstash-*'); | ||
|
|
||
| expect(callAdminCluster.calledOnce).to.be(true); |
There was a problem hiding this comment.
nit: since you're here already :)
sinon.assert.calledOnce(onBeforeWrite);
sinon.assert.calledOnce(callAdminCluster);
sinon.assert.calledWithExactly(callAdminCluster, 'delete', {
type: 'doc',
id: 'index-pattern:logstash-*',
refresh: 'wait_for',
index: '.kibana-test',
ignore: [404],
});There was a problem hiding this comment.
There is a lot of that in this file, but if you like!
There was a problem hiding this comment.
Pretty sure I'm falling in love with sinon's matcher API. I'm going to merge if the tests pass, but if you wouldn't mind double checking this commit @azasypkin, I would appreciate it
tasks/config/run.js
Outdated
| ...stdDevArgs, | ||
| '--optimize.enabled=false', | ||
| '--elasticsearch.url=' + esTestConfig.getUrl(), | ||
| '--elasticsearch.healthCheck.delay=360000', |
There was a problem hiding this comment.
question: just curious, why exactly 6 minutes? :)
There was a problem hiding this comment.
Haha, I'm horrible at math
|
|
||
| it('returns generic 404 when kibana index is missing', async () => ( | ||
| await supertest | ||
| .delete(`/api/saved_objects/dashboard/not-a-real-id`) |
There was a problem hiding this comment.
nit: maybe not-a-real-id ---> be3733a0-9efe-11e7-acb3-3dab96693fab just to be sure we get 404 because of missing index and not because of non-existing id.
|
@spalger I don't have anything new to add beyond @azasypkin's latest round of comments. |
6852b15 to
f98c009
Compare
* [savedObjects/delete+bulk_get] add failing tests * [savedObjects/delete+bulk_get] improve 404 handling * [savedObjects/client] fix mocha tests * [savedObjects/tests] remove extra test wrapper * [apiIntegration/kbnServer] basically disable es healthcheck * [savedObjects/create] add integration test * [savedObjects/find] add failing integration tests * [savedObjects/find] fix failing test * [savedObjects/client] explain reason for generic 404s * [savedObjects/get] add integration tests * [savedObjects/find] test request with unkown type * [savedObjects/find] add some more weird param tests * [savedObjects/find] test that weird params pass when no index * [savedObjects/update] use generic 404 * fix typos * [savedObjects/update] add integration tests * remove debugging uncomment * [savedObjects/tests] move backup kibana index delete out of tests * [savedObjects/tests/esArchives] remove logstash data * [savedObjects] update test * [uiSettings] remove detailed previously leaked from API * [functional/dashboard] wrap check that is only failing on Jenkins * [savedObjects/error] replace decorateNotFound with createGenericNotFound * fix typo * [savedObjectsClient/errors] fix decorateEsError() test * [savedObjectsClient] fix typos * [savedObjects/tests/functional] delete document that would normally exist * [savedObjectsClient/tests] use sinon assertions * [savedObjects/apiTests] create without index responds with 503 after #14202
|
6.x: ddc1d9c |
Currently when the Kibana index is missing the savedObjectsClient and APIs produce unexpected results. This PR tests and formalizes the following behaviors:
For those unfamiliar, run the API integration tests and dependencies in one go with:
To run the server/runner combo and for debugging run the following two commands in separate tabs: