diff --git a/changelogs/fragments/8565.yml b/changelogs/fragments/8565.yml new file mode 100644 index 000000000000..c555535dcf51 --- /dev/null +++ b/changelogs/fragments/8565.yml @@ -0,0 +1,2 @@ +feat: +- Adds editor footer to single line editor on focus ([#8565](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8565)) \ No newline at end of file diff --git a/changelogs/fragments/8693.yml b/changelogs/fragments/8693.yml new file mode 100644 index 000000000000..1e62413015f6 --- /dev/null +++ b/changelogs/fragments/8693.yml @@ -0,0 +1,2 @@ +fix: +- Update OTEL sample data description with compatible OS version ([#8693](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8693)) \ No newline at end of file diff --git a/src/plugins/data/common/data_frames/types.ts b/src/plugins/data/common/data_frames/types.ts index 9fe6deb75985..31d07f9a5070 100644 --- a/src/plugins/data/common/data_frames/types.ts +++ b/src/plugins/data/common/data_frames/types.ts @@ -121,7 +121,7 @@ export type IDataFrameResponse = SearchResponse & (IDataFrameDefaultResponse | IDataFramePollingResponse | IDataFrameErrorResponse); export interface IDataFrameError extends SearchResponse { - error: Error; + error: Error | string; } export interface PollQueryResultsParams { diff --git a/src/plugins/data/common/search/search_source/create_search_source.ts b/src/plugins/data/common/search/search_source/create_search_source.ts index 74b164369018..ed7a66d67a99 100644 --- a/src/plugins/data/common/search/search_source/create_search_source.ts +++ b/src/plugins/data/common/search/search_source/create_search_source.ts @@ -32,6 +32,7 @@ import { migrateLegacyQuery } from './migrate_legacy_query'; import { SearchSource, SearchSourceDependencies } from './search_source'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; import { SearchSourceFields } from './types'; +import { DEFAULT_DATA } from '../../constants'; /** * Deserializes a json string and a set of referenced objects to a `SearchSource` instance. @@ -57,8 +58,13 @@ export const createSearchSource = ( const fields = { ...searchSourceFields }; // hydrating index pattern - if (fields.index && typeof fields.index === 'string') { - fields.index = await indexPatterns.get(searchSourceFields.index as any); + if ( + fields.index && + typeof fields.index === 'string' && + (!fields.query?.dataset?.type || + fields.query.dataset.type === DEFAULT_DATA.SET_TYPES.INDEX_PATTERN) + ) { + fields.index = await indexPatterns.get(fields.index as string); } const searchSource = new SearchSource(fields, searchSourceDependencies); diff --git a/src/plugins/data/common/utils/helpers.ts b/src/plugins/data/common/utils/helpers.ts index 2d1ab2ab1417..1f10f9a320d8 100644 --- a/src/plugins/data/common/utils/helpers.ts +++ b/src/plugins/data/common/utils/helpers.ts @@ -28,7 +28,6 @@ * under the License. */ -import { i18n } from '@osd/i18n'; import { PollQueryResultsHandler, FetchStatusResponse } from '../data_frames'; export interface QueryStatusOptions { @@ -53,11 +52,7 @@ export const handleQueryResults = async ( } while (queryStatus !== 'SUCCESS' && queryStatus !== 'FAILED'); if (queryStatus === 'FAILED') { - throw new Error( - i18n.translate('data.search.request.failed', { - defaultMessage: 'An error occurred while executing the search query', - }) - ); + throw new Error(queryResultsRes?.body.error); } return queryResultsRes; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 773f24118907..e39722118721 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -68,8 +68,6 @@ export { DQLBody, SingleLineInput, DatasetSelector, - AdvancedSelector, - NoIndexPatternsPanel, DatasetSelectorAppearance, } from './ui'; diff --git a/src/plugins/data/public/query/query_string/language_service/lib/__snapshots__/query_result.test.tsx.snap b/src/plugins/data/public/query/query_string/language_service/lib/__snapshots__/query_result.test.tsx.snap index cec14cdb7fa2..a0fd2861a2b4 100644 --- a/src/plugins/data/public/query/query_string/language_service/lib/__snapshots__/query_result.test.tsx.snap +++ b/src/plugins/data/public/query/query_string/language_service/lib/__snapshots__/query_result.test.tsx.snap @@ -5,6 +5,8 @@ exports[`Query Result show error status with error message 2`] = ` anchorPosition="downRight" button={ Error @@ -31,28 +34,21 @@ exports[`Query Result show error status with error message 2`] = ` ERRORS
- - - Reasons: - - error reason -

- Details: + Message: - error details +

diff --git a/src/plugins/data/public/query/query_string/language_service/lib/_recent_query.scss b/src/plugins/data/public/query/query_string/language_service/lib/_recent_query.scss index 4b7a30ce85af..b932fe1adc33 100644 --- a/src/plugins/data/public/query/query_string/language_service/lib/_recent_query.scss +++ b/src/plugins/data/public/query/query_string/language_service/lib/_recent_query.scss @@ -7,3 +7,8 @@ background-color: $euiColorLightestShade; } } + +.editor_footerItem { + // Needed so the footer items never have paddings + padding: 0 !important; +} diff --git a/src/plugins/data/public/query/query_string/language_service/lib/query_result.tsx b/src/plugins/data/public/query/query_string/language_service/lib/query_result.tsx index 074ba4b5d0d5..2e8ab769e2e4 100644 --- a/src/plugins/data/public/query/query_string/language_service/lib/query_result.tsx +++ b/src/plugins/data/public/query/query_string/language_service/lib/query_result.tsx @@ -22,10 +22,9 @@ export interface QueryStatus { status: ResultStatus; body?: { error?: { - reason?: string; - details: string; + statusCode?: number; + message?: string; }; - statusCode?: number; }; elapsedMs?: number; startTime?: number; @@ -77,6 +76,22 @@ export function QueryResult(props: { queryStatus: QueryStatus }) {
); } + const time = Math.floor(elapsedTime / 1000); + return ( + {}} + isLoading + data-test-subj="queryResultLoading" + className="editor__footerItem" + > + {i18n.translate('data.query.languageService.queryResults.loadTime', { + defaultMessage: 'Loading {time} s', + values: { time }, + })} + + ); } if (props.queryStatus.status === ResultStatus.READY) { @@ -101,7 +116,13 @@ export function QueryResult(props: { queryStatus: QueryStatus }) { } return ( - {}}> + {}} + > {message} @@ -122,8 +143,10 @@ export function QueryResult(props: { queryStatus: QueryStatus }) { size="xs" onClick={onButtonClick} data-test-subj="queryResultErrorBtn" + className="editor__footerItem" + color="danger" > - + {i18n.translate('data.query.languageService.queryResults.error', { defaultMessage: `Error`, })} @@ -137,23 +160,15 @@ export function QueryResult(props: { queryStatus: QueryStatus }) { data-test-subj="queryResultError" > ERRORS -
- - - {i18n.translate('data.query.languageService.queryResults.reasons', { - defaultMessage: `Reasons:`, - })} - - {props.queryStatus.body.error.reason} - +

- {i18n.translate('data.query.languageService.queryResults.details', { - defaultMessage: `Details:`, + {i18n.translate('data.query.languageService.queryResults.message', { + defaultMessage: `Message:`, })} - - {props.queryStatus.body.error.details} + {' '} + {props.queryStatus.body.error.message}

diff --git a/src/plugins/data/public/ui/query_editor/_query_editor.scss b/src/plugins/data/public/ui/query_editor/_query_editor.scss index cf2321cf3d4e..d6577d33fdd3 100644 --- a/src/plugins/data/public/ui/query_editor/_query_editor.scss +++ b/src/plugins/data/public/ui/query_editor/_query_editor.scss @@ -218,3 +218,40 @@ display: block; } } + +.queryEditor__footer { + display: flex; + gap: 4px; + background: $euiColorLightestShade; + padding: 2px 4px; + margin-top: 5px; + margin-left: -5px; + margin-right: -5px; + z-index: 1; + position: relative; + align-items: center; +} + +.queryEditor__footerSpacer { + flex-grow: 1; +} + +.queryEditor__footerItem { + // Needed so the footer items never have paddings + padding: 0 !important; +} + +// TODO: Temporary workaround to disable padding for single line editor footer +.euiFormControlLayout--group.euiFormControlLayout--compressed .osdQuerEditor__singleLine .euiText { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.euiFormControlLayout--group .osdQuerEditor__singleLine .euiText { + background-color: unset !important; + line-height: 21px !important; +} + +.euiFormControlLayout--group .osdQuerEditor__singleLine .euiButtonEmpty { + border-right: 0; +} diff --git a/src/plugins/data/public/ui/query_editor/editors/shared.tsx b/src/plugins/data/public/ui/query_editor/editors/shared.tsx index 52370931da53..fb5df10c65c9 100644 --- a/src/plugins/data/public/ui/query_editor/editors/shared.tsx +++ b/src/plugins/data/public/ui/query_editor/editors/shared.tsx @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiCompressedFieldText } from '@elastic/eui'; +import { EuiCompressedFieldText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { monaco } from '@osd/monaco'; -import React from 'react'; +import React, { Fragment, useCallback, useRef, useState } from 'react'; import { CodeEditor } from '../../../../../opensearch_dashboards_react/public'; interface SingleLineInputProps extends React.JSX.IntrinsicAttributes { @@ -15,6 +15,7 @@ interface SingleLineInputProps extends React.JSX.IntrinsicAttributes { editorDidMount: (editor: any) => void; provideCompletionItems: monaco.languages.CompletionItemProvider['provideCompletionItems']; prepend?: React.ComponentProps['prepend']; + footerItems?: any; } type CollapsedComponent = React.ComponentType; @@ -61,59 +62,109 @@ export const SingleLineInput: React.FC = ({ editorDidMount, provideCompletionItems, prepend, -}) => ( -
- {prepend} -
- { + const [editorIsFocused, setEditorIsFocused] = useState(false); + const blurTimeoutRef = useRef(); + + const handleEditorDidMount = useCallback( + (editor: monaco.editor.IStandaloneCodeEditor) => { + editorDidMount(editor); + + const focusDisposable = editor.onDidFocusEditorText(() => { + if (blurTimeoutRef.current) { + clearTimeout(blurTimeoutRef.current); + } + setEditorIsFocused(true); + }); + + const blurDisposable = editor.onDidBlurEditorText(() => { + blurTimeoutRef.current = setTimeout(() => { + setEditorIsFocused(false); + }, 500); + }); + + return () => { + focusDisposable.dispose(); + blurDisposable.dispose(); + if (blurTimeoutRef.current) { + clearTimeout(blurTimeoutRef.current); + } + }; + }, + [editorDidMount] + ); + + return ( +
+ {prepend} +
+ + overviewRulerLanes: 0, + hideCursorInOverviewRuler: true, + cursorStyle: 'line', + wordBasedSuggestions: false, + }} + suggestionProvider={{ + provideCompletionItems, + triggerCharacters: [' '], + }} + languageConfiguration={{ + autoClosingPairs: [ + { + open: '(', + close: ')', + }, + { + open: '"', + close: '"', + }, + ], + }} + triggerSuggestOnFocus={true} + /> + {editorIsFocused && ( +
+ {footerItems && ( + + {footerItems.start?.map((item) => ( +
{item}
+ ))} +
+ {footerItems.end?.map((item) => ( +
{item}
+ ))} + + )} +
+ )} +
-
-); + ); +}; diff --git a/src/plugins/data/public/ui/query_editor/language_selector.tsx b/src/plugins/data/public/ui/query_editor/language_selector.tsx index 28ab7cf1acd2..31387c85c58f 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.tsx @@ -10,7 +10,7 @@ import { EuiSmallButtonEmpty, PopoverAnchorPosition, } from '@elastic/eui'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Query } from '../..'; import { LanguageConfig } from '../../query'; import { getQueryService } from '../../services'; @@ -36,12 +36,14 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { const queryString = getQueryService().queryString; const languageService = queryString.getLanguageService(); - const datasetSupportedLanguages = props.query.dataset - ? queryString - .getDatasetService() - .getType(props.query.dataset.type) - ?.supportedLanguages(props.query.dataset) - : undefined; + const datasetSupportedLanguages = useMemo(() => { + const dataset = props.query.dataset; + if (!dataset) { + return undefined; + } + const datasetType = queryString.getDatasetService().getType(dataset.type); + return datasetType?.supportedLanguages(dataset); + }, [props.query.dataset, queryString]); useEffect(() => { const subscription = queryString.getUpdates$().subscribe((query: Query) => { @@ -59,51 +61,58 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { setPopover(!isPopoverOpen); }; - const languageOptions: Array<{ label: string; value: string }> = []; - - languageService.getLanguages().forEach((language) => { - if ( - (language && props.appName && !language.editorSupportedAppNames?.includes(props.appName)) || - languageService.getUserQueryLanguageBlocklist().includes(language?.id) || - (datasetSupportedLanguages && !datasetSupportedLanguages.includes(language.id)) - ) - return; - languageOptions.unshift(mapExternalLanguageToOptions(language)); - }); - - const selectedLanguage = { - label: - (languageOptions.find( - (option) => (option.value as string).toLowerCase() === currentLanguage.toLowerCase() - )?.label as string) ?? languageOptions[0].label, - }; + const languageOptions = useMemo(() => { + const options: Array<{ label: string; value: string }> = []; - const handleLanguageChange = (newLanguage: string) => { - setCurrentLanguage(newLanguage); - props.onSelectLanguage(newLanguage); - }; + languageService.getLanguages().forEach((language) => { + const isSupported = + !datasetSupportedLanguages || datasetSupportedLanguages.includes(language.id); + const isBlocklisted = languageService.getUserQueryLanguageBlocklist().includes(language?.id); + const isAppSupported = + !props.appName || language?.editorSupportedAppNames?.includes(props.appName); + + if (!isSupported || isBlocklisted || !isAppSupported) return; + + options.unshift(mapExternalLanguageToOptions(language)); + }); - languageService.setUserQueryLanguage(currentLanguage); + return options.sort((a, b) => a.label.localeCompare(b.label)); + }, [languageService, props.appName, datasetSupportedLanguages]); + + const selectedLanguage = useMemo( + () => ({ + label: + languageOptions.find( + (option) => option.value.toLowerCase() === currentLanguage.toLowerCase() + )?.label ?? languageOptions[0]?.label, + }), + [languageOptions, currentLanguage] + ); + + const handleLanguageChange = useCallback( + (newLanguage: string) => { + setCurrentLanguage(newLanguage); + props.onSelectLanguage(newLanguage); + languageService.setUserQueryLanguage(newLanguage); + setPopover(false); + }, + [props, languageService] + ); - const languageOptionsMenu = languageOptions - .sort((a, b) => { - return a.label.localeCompare(b.label); - }) - .map((language) => { - return ( + const languageOptionsMenu = useMemo( + () => + languageOptions.map((language) => ( { - setPopover(false); - handleLanguageChange(language.value); - }} + onClick={() => handleLanguageChange(language.value)} > {language.label} - ); - }); + )), + [languageOptions, selectedLanguage.label, handleLanguageChange] + ); return ( { }, footerItems: { start: [ - + {`${this.state.lineCount} ${this.state.lineCount === 1 ? 'line' : 'lines'}`} , - + {this.props.query.dataset?.timeFieldName || ''} , , @@ -390,6 +395,7 @@ export default class QueryEditorUI extends Component { iconType="clock" size="xs" onClick={this.toggleRecentQueries} + className="queryEditor__footerItem" > {'Recent queries'} @@ -429,6 +435,34 @@ export default class QueryEditorUI extends Component { }, provideCompletionItems: this.provideCompletionItems, prepend: this.props.prepend, + footerItems: { + start: [ + + {`${this.state.lineCount ?? 1} ${ + this.state.lineCount === 1 || !this.state.lineCount ? 'line' : 'lines' + }`} + , + + {this.props.query.dataset?.timeFieldName || ''} + , + , + ], + end: [ + + + {'Recent queries'} + + , + ], + }, }; const languageEditorFunc = this.languageManager.getLanguage(this.props.query.language)!.editor; @@ -478,13 +512,13 @@ export default class QueryEditorUI extends Component { {!this.state.isCollapsed && ( <>
{languageEditor.Body()}
- )} + {this.renderQueryEditorExtensions()}
diff --git a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx index 026599d7fc65..bd1538384da1 100644 --- a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx +++ b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx @@ -11,7 +11,11 @@ import { RootState, DefaultViewState } from '../../../../../data_explorer/public import { buildColumns } from '../columns'; import * as utils from './common'; import { SortOrder } from '../../../saved_searches/types'; -import { DEFAULT_COLUMNS_SETTING, PLUGIN_ID } from '../../../../common'; +import { + DEFAULT_COLUMNS_SETTING, + PLUGIN_ID, + QUERY_ENHANCEMENT_ENABLED_SETTING, +} from '../../../../common'; export interface DiscoverState { /** @@ -90,7 +94,8 @@ export const getPreloadedState = async ({ const indexPatternId = savedSearchInstance.searchSource.getField('index')?.id; preloadedState.root = { metadata: { - indexPattern: indexPatternId, + ...(indexPatternId && + !config.get(QUERY_ENHANCEMENT_ENABLED_SETTING) && { indexPattern: indexPatternId }), view: PLUGIN_ID, }, }; diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts index 3796faea1142..50eba8d858de 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_search.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts @@ -150,6 +150,7 @@ export const useSearch = (services: DiscoverViewServices) => { if (!dataset) { data$.next({ status: shouldSearchOnPageLoad() ? ResultStatus.LOADING : ResultStatus.UNINITIALIZED, + queryStatus: { startTime }, }); return; } @@ -181,7 +182,7 @@ export const useSearch = (services: DiscoverViewServices) => { try { // Only show loading indicator if we are fetching when the rows are empty if (fetchStateRef.current.rows?.length === 0) { - data$.next({ status: ResultStatus.LOADING }); + data$.next({ status: ResultStatus.LOADING, queryStatus: { startTime } }); } // Initialize inspect adapter for search source @@ -272,15 +273,19 @@ export const useSearch = (services: DiscoverViewServices) => { } let errorBody; try { - errorBody = JSON.parse(error.message); + errorBody = JSON.parse(error.body); } catch (e) { - errorBody = error.message; + if (error.body) { + errorBody = error.body; + } else { + errorBody = error; + } } data$.next({ status: ResultStatus.ERROR, queryStatus: { - body: errorBody, + body: { error: errorBody }, elapsedMs, }, }); @@ -296,6 +301,7 @@ export const useSearch = (services: DiscoverViewServices) => { services, sort, savedSearch?.searchSource, + startTime, data$, shouldSearchOnPageLoad, inspectorAdapters.requests, @@ -352,18 +358,35 @@ export const useSearch = (services: DiscoverViewServices) => { useEffect(() => { (async () => { const savedSearchInstance = await getSavedSearchById(savedSearchId); - setSavedSearch(savedSearchInstance); - // if saved search does not exist, do not atempt to sync filters and query from savedObject - if (!savedSearch) { - return; + const query = + savedSearchInstance.searchSource.getField('query') || + data.query.queryString.getDefaultQuery(); + + const isEnhancementsEnabled = await uiSettings.get('query:enhancements:enabled'); + if (isEnhancementsEnabled && query.dataset) { + let pattern = await data.indexPatterns.get( + query.dataset.id, + query.dataset.type !== 'INDEX_PATTERN' + ); + if (!pattern) { + await data.query.queryString.getDatasetService().cacheDataset(query.dataset, { + uiSettings: services.uiSettings, + savedObjects: services.savedObjects, + notifications: services.notifications, + http: services.http, + data: services.data, + }); + pattern = await data.indexPatterns.get( + query.dataset.id, + query.dataset.type !== 'INDEX_PATTERN' + ); + savedSearchInstance.searchSource.setField('index', pattern); + } } // sync initial app filters from savedObject to filterManager const filters = cloneDeep(savedSearchInstance.searchSource.getOwnField('filter')); - const query = - savedSearchInstance.searchSource.getField('query') || - data.query.queryString.getDefaultQuery(); const actualFilters = []; if (filters !== undefined) { @@ -375,6 +398,7 @@ export const useSearch = (services: DiscoverViewServices) => { filterManager.setAppFilters(actualFilters); data.query.queryString.setQuery(query); + setSavedSearch(savedSearchInstance); if (savedSearchInstance?.id) { chrome.recentlyAccessed.add( @@ -387,8 +411,6 @@ export const useSearch = (services: DiscoverViewServices) => { ); } })(); - - return () => {}; // This effect will only run when getSavedSearchById is called, which is // only called when the component is first mounted. // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/plugins/home/server/services/sample_data/data_sets/otel/index.ts b/src/plugins/home/server/services/sample_data/data_sets/otel/index.ts index 6e83c85c5d4b..af6d5cec1536 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/otel/index.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/otel/index.ts @@ -21,7 +21,7 @@ const otelDataName = i18n.translate('home.sampleData.otelSpecTitle', { }); const otelDataDescription = i18n.translate('home.sampleData.otelSpecDescription', { defaultMessage: - 'Correlated observability signals for an e-commerce application in OpenTelemetry standard.', + 'Correlated observability signals for an e-commerce application in OpenTelemetry standard (Compatible with 2.13+ OpenSearch domains)', }); const initialAppLinks: AppLinkSchema[] = [ { diff --git a/src/plugins/query_enhancements/public/plugin.tsx b/src/plugins/query_enhancements/public/plugin.tsx index cbd40cb60b60..ef3512cb797b 100644 --- a/src/plugins/query_enhancements/public/plugin.tsx +++ b/src/plugins/query_enhancements/public/plugin.tsx @@ -96,7 +96,7 @@ export class QueryEnhancementsPlugin title: 'SQL', search: sqlSearchInterceptor, getQueryString: (query: Query) => { - return `SELECT * FROM ${queryString.getQuery().dataset?.title} LIMIT 10`; + return `SELECT * FROM ${query.dataset?.title} LIMIT 10`; }, fields: { filterable: false, diff --git a/src/plugins/query_enhancements/server/routes/index.ts b/src/plugins/query_enhancements/server/routes/index.ts index cb2dbc644189..dd17231adee2 100644 --- a/src/plugins/query_enhancements/server/routes/index.ts +++ b/src/plugins/query_enhancements/server/routes/index.ts @@ -85,8 +85,14 @@ export function defineSearchStrategyRouteProvider(logger: Logger, router: IRoute const queryRes: IDataFrameResponse = await searchStrategy.search(context, req as any, {}); return res.ok({ body: { ...queryRes } }); } catch (err) { + let error; + try { + error = JSON.parse(err.message); + } catch (e) { + error = err; + } return res.custom({ - statusCode: err.name, + statusCode: error.status, body: err.message, }); } diff --git a/src/plugins/query_enhancements/server/search/sql_async_search_strategy.ts b/src/plugins/query_enhancements/server/search/sql_async_search_strategy.ts index a48d47ce7826..9f3e7fd57e6f 100644 --- a/src/plugins/query_enhancements/server/search/sql_async_search_strategy.ts +++ b/src/plugins/query_enhancements/server/search/sql_async_search_strategy.ts @@ -82,7 +82,7 @@ export const sqlAsyncSearchStrategyProvider = ( type: DATA_FRAME_TYPES.POLLING, status: 'failed', body: { - error: new Error(`JOB: ${pollQueryResultsParams.queryId} failed`), + error: `JOB: ${inProgressQueryId} failed: ${queryStatusResponse.data.error}`, }, } as IDataFrameResponse; }