mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.14`: - [[Playground] Propagate Error message into FE (#182201)](https://github.com/elastic/kibana/pull/182201) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Samiul Monir","email":"150824886+Samiul-TheSoccerFan@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-05-01T14:22:41Z","message":"[Playground] Propagate Error message into FE (#182201)\n\n## Summary\r\n\r\n- Fix error not being propagated into FE\r\n- Added tests\r\n\r\n## UI\r\n\r\n### Rate limit error message:\r\n\r\n\r\n### BAD LLM\r\n\r\n\r\n### Invalid API key\r\n\r\n\r\n\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ] Any text added follows [EUI's writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\r\nsentence case text and includes [i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [ ] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n- [ ] Any UI touched in this PR is usable by keyboard only (learn more\r\nabout [keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n- [ ] Any UI touched in this PR does not create any new axe failures\r\n(run axe in browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n- [ ] If a plugin configuration key changed, check if it needs to be\r\nallowlisted in the cloud and added to the [docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n- [ ] This renders correctly on smaller devices using a responsive\r\nlayout. (You can test this [in your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n- [ ] This was checked for [cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"0288bb466403452dad0fe0958da9a2249a473072","branchLabelMapping":{"^v8.15.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:EnterpriseSearch","v8.14.0","v8.15.0"],"number":182201,"url":"https://github.com/elastic/kibana/pull/182201","mergeCommit":{"message":"[Playground] Propagate Error message into FE (#182201)\n\n## Summary\r\n\r\n- Fix error not being propagated into FE\r\n- Added tests\r\n\r\n## UI\r\n\r\n### Rate limit error message:\r\n\r\n\r\n### BAD LLM\r\n\r\n\r\n### Invalid API key\r\n\r\n\r\n\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ] Any text added follows [EUI's writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\r\nsentence case text and includes [i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [ ] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n- [ ] Any UI touched in this PR is usable by keyboard only (learn more\r\nabout [keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n- [ ] Any UI touched in this PR does not create any new axe failures\r\n(run axe in browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n- [ ] If a plugin configuration key changed, check if it needs to be\r\nallowlisted in the cloud and added to the [docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n- [ ] This renders correctly on smaller devices using a responsive\r\nlayout. (You can test this [in your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n- [ ] This was checked for [cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"0288bb466403452dad0fe0958da9a2249a473072"}},"sourceBranch":"main","suggestedTargetBranches":["8.14"],"targetPullRequestStates":[{"branch":"8.14","label":"v8.14.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.15.0","labelRegex":"^v8.15.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/182201","number":182201,"mergeCommit":{"message":"[Playground] Propagate Error message into FE (#182201)\n\n## Summary\r\n\r\n- Fix error not being propagated into FE\r\n- Added tests\r\n\r\n## UI\r\n\r\n### Rate limit error message:\r\n\r\n\r\n### BAD LLM\r\n\r\n\r\n### Invalid API key\r\n\r\n\r\n\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ] Any text added follows [EUI's writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\r\nsentence case text and includes [i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [ ] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n- [ ] Any UI touched in this PR is usable by keyboard only (learn more\r\nabout [keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n- [ ] Any UI touched in this PR does not create any new axe failures\r\n(run axe in browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n- [ ] If a plugin configuration key changed, check if it needs to be\r\nallowlisted in the cloud and added to the [docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n- [ ] This renders correctly on smaller devices using a responsive\r\nlayout. (You can test this [in your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n- [ ] This was checked for [cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"0288bb466403452dad0fe0958da9a2249a473072"}}]}] BACKPORT-->
This commit is contained in:
parent
eb58ab6f5f
commit
a37a090da8
4 changed files with 184 additions and 4 deletions
95
x-pack/plugins/search_playground/__mocks__/router.mock.ts
Normal file
95
x-pack/plugins/search_playground/__mocks__/router.mock.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
IRouter,
|
||||
KibanaRequest,
|
||||
RequestHandlerContext,
|
||||
RouteValidatorConfig,
|
||||
} from '@kbn/core/server';
|
||||
import { httpServiceMock, httpServerMock } from '@kbn/core/server/mocks';
|
||||
|
||||
/**
|
||||
* Test helper that mocks Kibana's router and DRYs out various helper (callRoute, schema validation)
|
||||
*/
|
||||
|
||||
type MethodType = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
||||
type PayloadType = 'params' | 'query' | 'body';
|
||||
|
||||
interface IMockRouter {
|
||||
method: MethodType;
|
||||
path: string;
|
||||
context?: jest.Mocked<RequestHandlerContext>;
|
||||
}
|
||||
interface IMockRouterRequest {
|
||||
body?: object;
|
||||
query?: object;
|
||||
params?: object;
|
||||
}
|
||||
type MockRouterRequest = KibanaRequest | IMockRouterRequest;
|
||||
|
||||
export class MockRouter {
|
||||
public router!: jest.Mocked<IRouter>;
|
||||
public method: MethodType;
|
||||
public path: string;
|
||||
public context: jest.Mocked<RequestHandlerContext>;
|
||||
public payload?: PayloadType;
|
||||
public response = httpServerMock.createResponseFactory();
|
||||
|
||||
constructor({ method, path, context = {} as jest.Mocked<RequestHandlerContext> }: IMockRouter) {
|
||||
this.createRouter();
|
||||
this.method = method;
|
||||
this.path = path;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public createRouter = () => {
|
||||
this.router = httpServiceMock.createRouter();
|
||||
};
|
||||
|
||||
public callRoute = async (request: MockRouterRequest) => {
|
||||
const route = this.findRouteRegistration();
|
||||
const [, handler] = route;
|
||||
await handler(this.context, httpServerMock.createKibanaRequest(request as any), this.response);
|
||||
};
|
||||
|
||||
/**
|
||||
* Schema validation helpers
|
||||
*/
|
||||
|
||||
public validateRoute = (request: MockRouterRequest) => {
|
||||
const route = this.findRouteRegistration();
|
||||
const [config] = route;
|
||||
const validate = config.validate as RouteValidatorConfig<{}, {}, {}>;
|
||||
const payloads = Object.keys(request) as PayloadType[];
|
||||
|
||||
payloads.forEach((payload: PayloadType) => {
|
||||
const payloadValidation = validate[payload] as { validate(request: KibanaRequest): void };
|
||||
const payloadRequest = request[payload] as KibanaRequest;
|
||||
|
||||
payloadValidation.validate(payloadRequest);
|
||||
});
|
||||
};
|
||||
|
||||
public shouldValidate = (request: MockRouterRequest) => {
|
||||
expect(() => this.validateRoute(request)).not.toThrow();
|
||||
};
|
||||
|
||||
public shouldThrow = (request: MockRouterRequest) => {
|
||||
expect(() => this.validateRoute(request)).toThrow();
|
||||
};
|
||||
|
||||
private findRouteRegistration = () => {
|
||||
const routerCalls = this.router[this.method].mock.calls as any[];
|
||||
if (!routerCalls.length) throw new Error('No routes registered.');
|
||||
|
||||
const route = routerCalls.find(([router]: any) => router.path === this.path);
|
||||
if (!route) throw new Error('No matching registered routes found - check method/path keys');
|
||||
|
||||
return route;
|
||||
};
|
||||
}
|
|
@ -5,7 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createRetriever } from './routes';
|
||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||
import { RequestHandlerContext } from '@kbn/core/server';
|
||||
import { coreMock } from '@kbn/core/server/mocks';
|
||||
import { MockRouter } from '../__mocks__/router.mock';
|
||||
import { ConversationalChain } from './lib/conversational_chain';
|
||||
import { getChatParams } from './lib/get_chat_params';
|
||||
import { createRetriever, defineRoutes } from './routes';
|
||||
|
||||
jest.mock('./lib/get_chat_params', () => ({
|
||||
getChatParams: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('./lib/conversational_chain');
|
||||
|
||||
describe('createRetriever', () => {
|
||||
test('works when the question has quotes', () => {
|
||||
|
@ -18,3 +30,75 @@ describe('createRetriever', () => {
|
|||
expect(result).toEqual({ query: { match: { text: 'How can I "do something" with quotes?' } } });
|
||||
});
|
||||
});
|
||||
|
||||
describe('Search Playground routes', () => {
|
||||
let mockRouter: MockRouter;
|
||||
const mockClient = {
|
||||
asCurrentUser: {},
|
||||
};
|
||||
|
||||
const mockCore = {
|
||||
elasticsearch: { client: mockClient },
|
||||
};
|
||||
const mockLogger = loggingSystemMock.createLogger().get();
|
||||
|
||||
describe('POST - Chat Messages', () => {
|
||||
const mockData = {
|
||||
connector_id: 'open-ai',
|
||||
indices: 'my-index',
|
||||
prompt: 'You are an assistant',
|
||||
citations: true,
|
||||
elasticsearch_query: {},
|
||||
summarization_model: 'GPT-4',
|
||||
doc_size: 3,
|
||||
source_fields: '{}',
|
||||
};
|
||||
|
||||
const mockRequestBody = {
|
||||
data: mockData,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
|
||||
const context = {
|
||||
core: Promise.resolve(mockCore),
|
||||
} as unknown as jest.Mocked<RequestHandlerContext>;
|
||||
|
||||
mockRouter = new MockRouter({
|
||||
context,
|
||||
method: 'post',
|
||||
path: '/internal/search_playground/chat',
|
||||
});
|
||||
|
||||
defineRoutes({
|
||||
logger: mockLogger,
|
||||
router: mockRouter.router,
|
||||
getStartServices: jest.fn().mockResolvedValue([coreStart, {}, {}]),
|
||||
});
|
||||
});
|
||||
|
||||
it('responds with error message if stream throws an error', async () => {
|
||||
(getChatParams as jest.Mock).mockResolvedValue({ model: 'open-ai' });
|
||||
(ConversationalChain as jest.Mock).mockImplementation(() => {
|
||||
return {
|
||||
stream: jest
|
||||
.fn()
|
||||
.mockRejectedValue(new Error('Unexpected API error - Some Open AI error message')),
|
||||
};
|
||||
});
|
||||
|
||||
await mockRouter.callRoute({
|
||||
body: mockRequestBody,
|
||||
});
|
||||
|
||||
expect(mockRouter.response.badRequest).toHaveBeenCalledWith({
|
||||
body: {
|
||||
message: 'Unexpected API error - Some Open AI error message',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -131,10 +131,10 @@ export function defineRoutes({
|
|||
} catch (e) {
|
||||
logger.error('Failed to create the chat stream', e);
|
||||
|
||||
if (typeof e === 'string') {
|
||||
if (typeof e === 'object') {
|
||||
return response.badRequest({
|
||||
body: {
|
||||
message: e,
|
||||
message: e.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
"@kbn/triggers-actions-ui-plugin",
|
||||
"@kbn/elastic-assistant-common",
|
||||
"@kbn/logging",
|
||||
"@kbn/doc-links"
|
||||
"@kbn/doc-links",
|
||||
"@kbn/core-logging-server-mocks"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue