redact ES client errors (#171018)

## Summary

Define a custom `toJSON` method on errors from the ES client to have
better control of the format of the output of their JSON serialization
This commit is contained in:
Pierre Gayvallet 2023-11-10 15:42:14 +01:00 committed by GitHub
parent b0862085f6
commit c43e6997af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 0 deletions

View file

@ -13,9 +13,13 @@ import { parseClientOptions } from './client_config';
import { instrumentEsQueryAndDeprecationLogger } from './log_query_and_deprecation';
import { createTransport } from './create_transport';
import type { AgentFactoryProvider } from './agent_manager';
import { patchElasticsearchClient } from './patch_client';
const noop = () => undefined;
// Apply ES client patches on module load
patchElasticsearchClient();
export const configureClient = (
config: ElasticsearchClientConfig,
{

View file

@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { errors } from '@elastic/elasticsearch';
export const patchElasticsearchClient = () => {
const baseErrorPrototype = errors.ElasticsearchClientError.prototype;
// @ts-expect-error
baseErrorPrototype.toJSON = function () {
return {
name: this.name,
message: this.message,
};
};
};

View file

@ -0,0 +1,70 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
createTestServers,
type TestElasticsearchUtils,
type TestKibanaUtils,
} from '@kbn/core-test-helpers-kbn-server';
describe('elasticsearch clients errors', () => {
let esServer: TestElasticsearchUtils;
let kibanaServer: TestKibanaUtils;
beforeAll(async () => {
const { startES, startKibana } = createTestServers({
adjustTimeout: jest.setTimeout,
});
esServer = await startES();
kibanaServer = await startKibana();
});
afterAll(async () => {
await kibanaServer.stop();
await esServer.stop();
});
it('has the proper JSON representation', async () => {
const esClient = kibanaServer.coreStart.elasticsearch.client.asInternalUser;
try {
await esClient.search({
index: '.kibana',
// @ts-expect-error yes this is invalid
query: { someInvalidQuery: { foo: 'bar' } },
});
expect('should have thrown').toEqual('but it did not');
} catch (e) {
expect(JSON.stringify(e)).toMatchInlineSnapshot(
`"{\\"name\\":\\"ResponseError\\",\\"message\\":\\"parsing_exception\\\\n\\\\tCaused by:\\\\n\\\\t\\\\tnamed_object_not_found_exception: [1:30] unknown field [someInvalidQuery]\\\\n\\\\tRoot causes:\\\\n\\\\t\\\\tparsing_exception: unknown query [someInvalidQuery]\\"}"`
);
}
});
it('has the proper string representation', async () => {
const esClient = kibanaServer.coreStart.elasticsearch.client.asInternalUser;
try {
await esClient.search({
index: '.kibana',
// @ts-expect-error yes this is invalid
query: { someInvalidQuery: { foo: 'bar' } },
});
expect('should have thrown').toEqual('but it did not');
} catch (e) {
expect(String(e)).toMatchInlineSnapshot(`
"ResponseError: parsing_exception
Caused by:
named_object_not_found_exception: [1:30] unknown field [someInvalidQuery]
Root causes:
parsing_exception: unknown query [someInvalidQuery]"
`);
}
});
});