diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.indexpattern.md new file mode 100644 index 0000000000000..baf44de5088fb --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.indexpattern.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchOptions](./kibana-plugin-plugins-data-public.isearchoptions.md) > [indexPattern](./kibana-plugin-plugins-data-public.isearchoptions.indexpattern.md) + +## ISearchOptions.indexPattern property + +Index pattern reference is used for better error messages + +Signature: + +```typescript +indexPattern?: IndexPattern; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.md index fc2767cd0231f..2473c9cfdde8d 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchoptions.md @@ -15,6 +15,7 @@ export interface ISearchOptions | Property | Type | Description | | --- | --- | --- | | [abortSignal](./kibana-plugin-plugins-data-public.isearchoptions.abortsignal.md) | AbortSignal | An AbortSignal that allows the caller of search to abort a search request. | +| [indexPattern](./kibana-plugin-plugins-data-public.isearchoptions.indexpattern.md) | IndexPattern | Index pattern reference is used for better error messages | | [isRestore](./kibana-plugin-plugins-data-public.isearchoptions.isrestore.md) | boolean | Whether the session is restored (i.e. search requests should re-use the stored search IDs, rather than starting from scratch) | | [isStored](./kibana-plugin-plugins-data-public.isearchoptions.isstored.md) | boolean | Whether the session is already saved (i.e. sent to background) | | [legacyHitsTotal](./kibana-plugin-plugins-data-public.isearchoptions.legacyhitstotal.md) | boolean | Request the legacy format for the total number of hits. If sending rest_total_hits_as_int to something other than true, this should be set to false. | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md index 5f43f8477cb9f..b8f21de3e086e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md @@ -9,7 +9,7 @@ Constructs a new instance of the `PainlessError` class Signature: ```typescript -constructor(err: IEsError); +constructor(err: IEsError, indexPattern?: IndexPattern); ``` ## Parameters @@ -17,4 +17,5 @@ constructor(err: IEsError); | Parameter | Type | Description | | --- | --- | --- | | err | IEsError | | +| indexPattern | IndexPattern | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md new file mode 100644 index 0000000000000..4312f2f8d0c91 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) > [indexPattern](./kibana-plugin-plugins-data-public.painlesserror.indexpattern.md) + +## PainlessError.indexPattern property + +Signature: + +```typescript +indexPattern?: IndexPattern; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md index c77b8b259136b..3a887d358e215 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md @@ -14,12 +14,13 @@ export declare class PainlessError extends EsError | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)(err)](./kibana-plugin-plugins-data-public.painlesserror._constructor_.md) | | Constructs a new instance of the PainlessError class | +| [(constructor)(err, indexPattern)](./kibana-plugin-plugins-data-public.painlesserror._constructor_.md) | | Constructs a new instance of the PainlessError class | ## Properties | Property | Modifiers | Type | Description | | --- | --- | --- | --- | +| [indexPattern](./kibana-plugin-plugins-data-public.painlesserror.indexpattern.md) | | IndexPattern | | | [painlessStack](./kibana-plugin-plugins-data-public.painlesserror.painlessstack.md) | | string | | ## Methods diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.indexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.indexpattern.md new file mode 100644 index 0000000000000..cc24363c1bed5 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.indexpattern.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchOptions](./kibana-plugin-plugins-data-server.isearchoptions.md) > [indexPattern](./kibana-plugin-plugins-data-server.isearchoptions.indexpattern.md) + +## ISearchOptions.indexPattern property + +Index pattern reference is used for better error messages + +Signature: + +```typescript +indexPattern?: IndexPattern; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md index 9de351b2b9019..7fd4dd5b8e566 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md @@ -15,6 +15,7 @@ export interface ISearchOptions | Property | Type | Description | | --- | --- | --- | | [abortSignal](./kibana-plugin-plugins-data-server.isearchoptions.abortsignal.md) | AbortSignal | An AbortSignal that allows the caller of search to abort a search request. | +| [indexPattern](./kibana-plugin-plugins-data-server.isearchoptions.indexpattern.md) | IndexPattern | Index pattern reference is used for better error messages | | [isRestore](./kibana-plugin-plugins-data-server.isearchoptions.isrestore.md) | boolean | Whether the session is restored (i.e. search requests should re-use the stored search IDs, rather than starting from scratch) | | [isStored](./kibana-plugin-plugins-data-server.isearchoptions.isstored.md) | boolean | Whether the session is already saved (i.e. sent to background) | | [legacyHitsTotal](./kibana-plugin-plugins-data-server.isearchoptions.legacyhitstotal.md) | boolean | Request the legacy format for the total number of hits. If sending rest_total_hits_as_int to something other than true, this should be set to false. | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md index ea3ba28a52def..9dc38f96df4be 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md @@ -12,7 +12,7 @@ start(core: CoreStart): { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; indexPatterns: { - indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise; + indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise; }; search: ISearchStart>; }; @@ -31,7 +31,7 @@ start(core: CoreStart): { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; indexPatterns: { - indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise; + indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise; }; search: ISearchStart>; }` diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index 1c1360414cb2e..dc685e927c237 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -296,6 +296,9 @@ export class SearchSource { switchMap(() => { const searchRequest = this.flatten(); this.history = [searchRequest]; + if (searchRequest.index) { + options.indexPattern = searchRequest.index; + } return getConfig(UI_SETTINGS.COURIER_BATCH_SEARCHES) ? from(this.legacyFetch(searchRequest, options)) diff --git a/src/plugins/data/common/search/types.ts b/src/plugins/data/common/search/types.ts index 4f687a396a47b..3ac4c33091f6b 100644 --- a/src/plugins/data/common/search/types.ts +++ b/src/plugins/data/common/search/types.ts @@ -8,6 +8,7 @@ import { Observable } from 'rxjs'; import { IEsSearchRequest, IEsSearchResponse } from './es_search'; +import { IndexPattern } from '..'; export type ISearchGeneric = < SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, @@ -111,4 +112,10 @@ export interface ISearchOptions { * rather than starting from scratch) */ isRestore?: boolean; + + /** + * Index pattern reference is used for better error messages + */ + + indexPattern?: IndexPattern; } diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 4668ce2208610..4dfce45d11bea 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1640,6 +1640,7 @@ export type ISearchGeneric = { }); const component = mount(e.getErrorMessage(startMock.application)); - const scriptElem = findTestSubject(component, 'painlessScript').getDOMNode(); - const failedShards = e.attributes?.failed_shards![0]; - const script = failedShards!.reason.script; - expect(scriptElem.textContent).toBe(`Error executing Painless script: '${script}'`); const stackTraceElem = findTestSubject(component, 'painlessStackTrace').getDOMNode(); - const stackTrace = failedShards!.reason.script_stack!.join('\n'); + const stackTrace = failedShards!.reason.script_stack!.splice(-2).join('\n'); expect(stackTraceElem.textContent).toBe(stackTrace); + const humanReadableError = findTestSubject( + component, + 'painlessHumanReadableError' + ).getDOMNode(); + expect(humanReadableError.textContent).toBe(failedShards?.reason.caused_by?.reason); + expect(component.find('EuiButton').length).toBe(1); }); }); diff --git a/src/plugins/data/public/search/errors/painless_error.tsx b/src/plugins/data/public/search/errors/painless_error.tsx index a73d112a8de48..bad4567024d00 100644 --- a/src/plugins/data/public/search/errors/painless_error.tsx +++ b/src/plugins/data/public/search/errors/painless_error.tsx @@ -14,40 +14,59 @@ import { ApplicationStart } from 'kibana/public'; import { IEsError, isEsError } from './types'; import { EsError } from './es_error'; import { getRootCause } from './utils'; +import { IndexPattern } from '../..'; export class PainlessError extends EsError { painlessStack?: string; - constructor(err: IEsError) { + indexPattern?: IndexPattern; + constructor(err: IEsError, indexPattern?: IndexPattern) { super(err); + this.indexPattern = indexPattern; } public getErrorMessage(application: ApplicationStart) { - function onClick() { + function onClick(indexPatternId?: string) { application.navigateToApp('management', { - path: `/kibana/indexPatterns`, + path: `/kibana/indexPatterns${indexPatternId ? `/patterns/${indexPatternId}` : ''}`, }); } const rootCause = getRootCause(this.err); + const scriptFromStackTrace = rootCause?.script_stack + ? rootCause?.script_stack?.slice(-2).join('\n') + : undefined; + // if the error has been properly processed it will highlight where it occurred. + const hasScript = rootCause?.script_stack?.slice(-1)[0]?.indexOf('HERE') || -1 >= 0; + const humanReadableError = rootCause?.caused_by?.reason; + // fallback, show ES stacktrace const painlessStack = rootCause?.script_stack ? rootCause?.script_stack.join('\n') : undefined; + const indexPatternId = this?.indexPattern?.id; return ( <> - + {i18n.translate('data.painlessError.painlessScriptedFieldErrorMessage', { - defaultMessage: "Error executing Painless script: '{script}'", - values: { script: rootCause?.script }, + defaultMessage: + 'Error executing runtime field or scripted field on index pattern {indexPatternName}', + values: { + indexPatternName: this?.indexPattern?.title, + }, })} - {painlessStack ? ( + {scriptFromStackTrace || painlessStack ? ( - {painlessStack} + {hasScript ? scriptFromStackTrace : painlessStack} ) : null} + {humanReadableError ? ( + {humanReadableError} + ) : null} + + - + onClick(indexPatternId)} size="s"> diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index f33740cc45bf9..2500424e87578 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -109,7 +109,7 @@ export class SearchInterceptor { return e; } else if (isEsError(e)) { if (isPainlessError(e)) { - return new PainlessError(e); + return new PainlessError(e, options?.indexPattern); } else { return new EsError(e); } diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index ab8f6c9ed3951..23aaab36e7905 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -912,6 +912,7 @@ export class IndexPatternsService implements Plugin_3