[7.x] [HTTP] Apply the same behaviour to all 500 errors (except from custom responses) (#85541) (#91892)

* [HTTP] Apply the same behaviour to all 500 errors (except from `custom` responses) (#85541)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	x-pack/plugins/security/server/routes/authentication/saml.ts

* Fix deprecated route

* Mock before calling the method
This commit is contained in:
Alejandro Fernández Haro 2021-02-18 22:17:02 +00:00 committed by GitHub
parent 890ddce74f
commit 6da1e935bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
163 changed files with 1036 additions and 1443 deletions

View file

@ -19,7 +19,6 @@ kibanaResponseFactory: {
forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
notFound: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; notFound: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
conflict: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; conflict: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
internalError: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
customError: (options: CustomHttpResponseOptions<ResponseError>) => KibanaResponse<ResponseError>; customError: (options: CustomHttpResponseOptions<ResponseError>) => KibanaResponse<ResponseError>;
redirected: (options: RedirectResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>; redirected: (options: RedirectResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>;
ok: (options?: HttpResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>; ok: (options?: HttpResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>;

View file

@ -283,7 +283,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [PluginOpaqueId](./kibana-plugin-core-server.pluginopaqueid.md) | | | [PluginOpaqueId](./kibana-plugin-core-server.pluginopaqueid.md) | |
| [PublicUiSettingsParams](./kibana-plugin-core-server.publicuisettingsparams.md) | A sub-set of [UiSettingsParams](./kibana-plugin-core-server.uisettingsparams.md) exposed to the client-side. | | [PublicUiSettingsParams](./kibana-plugin-core-server.publicuisettingsparams.md) | A sub-set of [UiSettingsParams](./kibana-plugin-core-server.uisettingsparams.md) exposed to the client-side. |
| [RedirectResponseOptions](./kibana-plugin-core-server.redirectresponseoptions.md) | HTTP response parameters for redirection response | | [RedirectResponseOptions](./kibana-plugin-core-server.redirectresponseoptions.md) | HTTP response parameters for redirection response |
| [RequestHandler](./kibana-plugin-core-server.requesthandler.md) | A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) functions. | | [RequestHandler](./kibana-plugin-core-server.requesthandler.md) | A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) functions. If anything else is returned, or an error is thrown, the HTTP service will automatically log the error and respond <code>500 - Internal Server Error</code>. |
| [RequestHandlerContextContainer](./kibana-plugin-core-server.requesthandlercontextcontainer.md) | An object that handles registration of http request context providers. | | [RequestHandlerContextContainer](./kibana-plugin-core-server.requesthandlercontextcontainer.md) | An object that handles registration of http request context providers. |
| [RequestHandlerContextProvider](./kibana-plugin-core-server.requesthandlercontextprovider.md) | Context provider for request handler. Extends request context object with provided functionality or data. | | [RequestHandlerContextProvider](./kibana-plugin-core-server.requesthandlercontextprovider.md) | Context provider for request handler. Extends request context object with provided functionality or data. |
| [RequestHandlerWrapper](./kibana-plugin-core-server.requesthandlerwrapper.md) | Type-safe wrapper for [RequestHandler](./kibana-plugin-core-server.requesthandler.md) function. | | [RequestHandlerWrapper](./kibana-plugin-core-server.requesthandlerwrapper.md) | Type-safe wrapper for [RequestHandler](./kibana-plugin-core-server.requesthandler.md) function. |

View file

@ -4,7 +4,7 @@
## RequestHandler type ## RequestHandler type
A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) functions. A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) functions. If anything else is returned, or an error is thrown, the HTTP service will automatically log the error and respond `500 - Internal Server Error`<!-- -->.
<b>Signature:</b> <b>Signature:</b>

View file

@ -705,12 +705,8 @@ describe('BasePathProxyServer', () => {
options: { body: { output: 'stream' } }, options: { body: { output: 'stream' } },
}, },
(_, req, res) => { (_, req, res) => {
try { expect(req.body).toBeInstanceOf(Readable);
expect(req.body).toBeInstanceOf(Readable); return res.ok({ body: req.route.options.body });
return res.ok({ body: req.route.options.body });
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -740,15 +736,11 @@ describe('BasePathProxyServer', () => {
}, },
}, },
(_, req, res) => { (_, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -779,15 +771,11 @@ describe('BasePathProxyServer', () => {
}, },
}, },
(context, req, res) => { (context, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -815,15 +803,11 @@ describe('BasePathProxyServer', () => {
}, },
}, },
(_, req, res) => { (_, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -851,15 +835,11 @@ describe('BasePathProxyServer', () => {
}, },
}, },
(_, req, res) => { (_, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);

View file

@ -151,7 +151,6 @@ const createResponseFactoryMock = (): jest.Mocked<KibanaResponseFactory> => ({
forbidden: jest.fn(), forbidden: jest.fn(),
notFound: jest.fn(), notFound: jest.fn(),
conflict: jest.fn(), conflict: jest.fn(),
internalError: jest.fn(),
customError: jest.fn(), customError: jest.fn(),
}); });
@ -162,7 +161,6 @@ const createLifecycleResponseFactoryMock = (): jest.Mocked<LifecycleResponseFact
forbidden: jest.fn(), forbidden: jest.fn(),
notFound: jest.fn(), notFound: jest.fn(),
conflict: jest.fn(), conflict: jest.fn(),
internalError: jest.fn(),
customError: jest.fn(), customError: jest.fn(),
}); });

View file

@ -1016,13 +1016,9 @@ describe('body options', () => {
options: { body: { parse: false } }, options: { body: { parse: false } },
}, },
(context, req, res) => { (context, req, res) => {
try { expect(req.body).toBeInstanceOf(Buffer);
expect(req.body).toBeInstanceOf(Buffer); expect(req.body.toString()).toBe(JSON.stringify({ test: 1 }));
expect(req.body.toString()).toBe(JSON.stringify({ test: 1 })); return res.ok({ body: req.route.options.body });
return res.ok({ body: req.route.options.body });
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -1053,15 +1049,11 @@ describe('timeout options', () => {
}, },
}, },
(context, req, res) => { (context, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -1091,15 +1083,11 @@ describe('timeout options', () => {
}, },
}, },
(context, req, res) => { (context, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -1128,15 +1116,11 @@ describe('timeout options', () => {
}, },
}, },
(context, req, res) => { (context, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -1165,15 +1149,11 @@ describe('timeout options', () => {
}, },
}, },
(context, req, res) => { (context, req, res) => {
try { return res.ok({
return res.ok({ body: {
body: { timeout: req.route.options.timeout,
timeout: req.route.options.timeout, },
}, });
});
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);
@ -1294,12 +1274,8 @@ test('should return a stream in the body', async () => {
options: { body: { output: 'stream' } }, options: { body: { output: 'stream' } },
}, },
(context, req, res) => { (context, req, res) => {
try { expect(req.body).toBeInstanceOf(Readable);
expect(req.body).toBeInstanceOf(Readable); return res.ok({ body: req.route.options.body });
return res.ok({ body: req.route.options.body });
} catch (err) {
return res.internalError({ body: err.message });
}
} }
); );
registerRouter(router); registerRouter(router);

View file

@ -1672,7 +1672,11 @@ describe('Response factory', () => {
const result = await supertest(innerServer.listener).get('/').expect(500); const result = await supertest(innerServer.listener).get('/').expect(500);
expect(result.body.message).toBe('reason'); expect(result.body).toEqual({
error: 'Internal Server Error',
message: 'reason',
statusCode: 500,
});
expect(loggingSystemMock.collect(logger).error).toHaveLength(0); expect(loggingSystemMock.collect(logger).error).toHaveLength(0);
}); });

View file

@ -177,15 +177,6 @@ const errorResponseFactory = {
conflict: (options: ErrorHttpResponseOptions = {}) => conflict: (options: ErrorHttpResponseOptions = {}) =>
new KibanaResponse(409, options.body || 'Conflict', options), new KibanaResponse(409, options.body || 'Conflict', options),
// Server error
/**
* The server encountered an unexpected condition that prevented it from fulfilling the request.
* Status code: `500`.
* @param options - {@link HttpResponseOptions} configures HTTP response headers, error message and other error details to pass to the client
*/
internalError: (options: ErrorHttpResponseOptions = {}) =>
new KibanaResponse(500, options.body || 'Internal Error', options),
/** /**
* Creates an error response with defined status code and payload. * Creates an error response with defined status code and payload.
* @param options - {@link CustomHttpResponseOptions} configures HTTP response headers, error message and other error details to pass to the client * @param options - {@link CustomHttpResponseOptions} configures HTTP response headers, error message and other error details to pass to the client

View file

@ -314,6 +314,8 @@ type RequestHandlerEnhanced<P, Q, B, Method extends RouteMethod> = WithoutHeadAr
/** /**
* A function executed when route path matched requested resource path. * A function executed when route path matched requested resource path.
* Request handler is expected to return a result of one of {@link KibanaResponseFactory} functions. * Request handler is expected to return a result of one of {@link KibanaResponseFactory} functions.
* If anything else is returned, or an error is thrown, the HTTP service will automatically log the error
* and respond `500 - Internal Server Error`.
* @param context {@link RequestHandlerContext} - the core context exposed for this request. * @param context {@link RequestHandlerContext} - the core context exposed for this request.
* @param request {@link KibanaRequest} - object containing information about requested resource, * @param request {@link KibanaRequest} - object containing information about requested resource,
* such as path, method, headers, parameters, query, body, etc. * such as path, method, headers, parameters, query, body, etc.

View file

@ -1276,7 +1276,6 @@ export const kibanaResponseFactory: {
forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
notFound: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; notFound: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
conflict: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>; conflict: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
internalError: (options?: ErrorHttpResponseOptions) => KibanaResponse<ResponseError>;
customError: (options: CustomHttpResponseOptions<ResponseError>) => KibanaResponse<ResponseError>; customError: (options: CustomHttpResponseOptions<ResponseError>) => KibanaResponse<ResponseError>;
redirected: (options: RedirectResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>; redirected: (options: RedirectResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>;
ok: (options?: HttpResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>; ok: (options?: HttpResponseOptions) => KibanaResponse<string | Record<string, any> | Buffer | Stream>;
@ -3197,7 +3196,7 @@ export const validBodyOutput: readonly ["data", "stream"];
// Warnings were encountered during analysis: // Warnings were encountered during analysis:
// //
// src/core/server/http/router/response.ts:306:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts // src/core/server/http/router/response.ts:297:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:280:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:280:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:280:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:280:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:283:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:283:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts

View file

@ -57,17 +57,13 @@ export function registerValueSuggestionsRoute(
const field = indexPattern && getFieldByName(fieldName, indexPattern); const field = indexPattern && getFieldByName(fieldName, indexPattern);
const body = await getBody(autocompleteSearchOptions, field || fieldName, query, filters); const body = await getBody(autocompleteSearchOptions, field || fieldName, query, filters);
try { const result = await client.callAsCurrentUser('search', { index, body }, { signal });
const result = await client.callAsCurrentUser('search', { index, body }, { signal });
const buckets: any[] = const buckets: any[] =
get(result, 'aggregations.suggestions.buckets') || get(result, 'aggregations.suggestions.buckets') ||
get(result, 'aggregations.nestedSuggestions.suggestions.buckets'); get(result, 'aggregations.nestedSuggestions.suggestions.buckets');
return response.ok({ body: map(buckets || [], 'key') }); return response.ok({ body: map(buckets || [], 'key') });
} catch (error) {
return response.internalError({ body: error });
}
} }
); );
} }

View file

@ -38,5 +38,5 @@ export const handleEsError = ({
}); });
} }
// Case: default // Case: default
return response.internalError({ body: error }); throw error;
}; };

View file

@ -136,8 +136,7 @@ export function createInstallRoute(
(counts as any)[index] = count; (counts as any)[index] = count;
} catch (err) { } catch (err) {
const errMsg = `sample_data install errors while loading data. Error: ${err}`; const errMsg = `sample_data install errors while loading data. Error: ${err}`;
logger.warn(errMsg); throw new Error(errMsg);
return res.internalError({ body: errMsg });
} }
} }
@ -157,8 +156,7 @@ export function createInstallRoute(
); );
} catch (err) { } catch (err) {
const errMsg = `bulkCreate failed, error: ${err.message}`; const errMsg = `bulkCreate failed, error: ${err.message}`;
logger.warn(errMsg); throw new Error(errMsg);
return res.internalError({ body: errMsg });
} }
const errors = createResults.saved_objects.filter((savedObjectCreateResult) => { const errors = createResults.saved_objects.filter((savedObjectCreateResult) => {
return Boolean(savedObjectCreateResult.error); return Boolean(savedObjectCreateResult.error);

View file

@ -77,46 +77,32 @@ export function runRoute(
}, },
}, },
router.handleLegacyErrors(async (context, request, response) => { router.handleLegacyErrors(async (context, request, response) => {
try { const [, { data }] = await core.getStartServices();
const [, { data }] = await core.getStartServices(); const uiSettings = await context.core.uiSettings.client.getAll();
const uiSettings = await context.core.uiSettings.client.getAll(); const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory(
const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory( context.core.savedObjects.client,
context.core.savedObjects.client, context.core.elasticsearch.client.asCurrentUser
context.core.elasticsearch.client.asCurrentUser );
);
const tlConfig = getTlConfig({ const tlConfig = getTlConfig({
context, context,
request, request,
settings: _.defaults(uiSettings, timelionDefaults), // Just in case they delete some setting. settings: _.defaults(uiSettings, timelionDefaults), // Just in case they delete some setting.
getFunction, getFunction,
getIndexPatternsService: () => indexPatternsService, getIndexPatternsService: () => indexPatternsService,
getStartServices: core.getStartServices, getStartServices: core.getStartServices,
allowedGraphiteUrls: configManager.getGraphiteUrls(), allowedGraphiteUrls: configManager.getGraphiteUrls(),
esShardTimeout: configManager.getEsShardTimeout(), esShardTimeout: configManager.getEsShardTimeout(),
}); });
const chainRunner = chainRunnerFn(tlConfig); const chainRunner = chainRunnerFn(tlConfig);
const sheet = await Bluebird.all(chainRunner.processRequest(request.body)); const sheet = await Bluebird.all(chainRunner.processRequest(request.body));
return response.ok({ return response.ok({
body: { body: {
sheet, sheet,
stats: chainRunner.getStats(), stats: chainRunner.getStats(),
}, },
}); });
} catch (err) {
logger.error(`${err.toString()}: ${err.stack}`);
// TODO Maybe we should just replace everywhere we throw with Boom? Probably.
if (err.isBoom) {
throw err;
} else {
return response.internalError({
body: {
message: err.toString(),
},
});
}
}
}) })
); );
} }

View file

@ -42,18 +42,12 @@ export const visDataRoutes = (router: VisTypeTimeseriesRouter, framework: Framew
); );
} }
try { const results = await getVisData(
const results = await getVisData( requestContext,
requestContext, request as KibanaRequest<{}, {}, GetVisDataOptions>,
request as KibanaRequest<{}, {}, GetVisDataOptions>, framework
framework );
); return response.ok({ body: results });
return response.ok({ body: results });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -34,7 +34,7 @@ export class NewsFeedSimulatorPlugin implements Plugin {
options: { authRequired: false }, options: { authRequired: false },
}, },
(context, req, res) => { (context, req, res) => {
return res.internalError({ body: new Error('Internal server error') }); throw new Error('Internal server error');
} }
); );
} }

View file

@ -18,7 +18,7 @@ export class CorePluginBPlugin implements Plugin {
public setup(core: CoreSetup, deps: {}) { public setup(core: CoreSetup, deps: {}) {
const router = core.http.createRouter<PluginBContext>(); const router = core.http.createRouter<PluginBContext>();
router.get({ path: '/core_plugin_b', validate: false }, async (context, req, res) => { router.get({ path: '/core_plugin_b', validate: false }, async (context, req, res) => {
if (!context.pluginA) return res.internalError({ body: 'pluginA is disabled' }); if (!context.pluginA) throw new Error('pluginA is disabled');
const response = await context.pluginA.ping(); const response = await context.pluginA.ping();
return res.ok({ body: `Pong via plugin A: ${response}` }); return res.ok({ body: `Pong via plugin A: ${response}` });
}); });

View file

@ -50,11 +50,7 @@ export const registerCreateTokenRoute = (router: BeatsManagementRouter) => {
}); });
} catch (err) { } catch (err) {
beatsManagement.framework.log(err.message); beatsManagement.framework.log(err.message);
return response.internalError({ throw new Error('An error occurred, please check your Kibana logs');
body: {
message: 'An error occurred, please check your Kibana logs',
},
});
} }
} }
) )

View file

@ -20,7 +20,7 @@ export const catchErrorHandler: <P, Q, B>(
statusCode: error.output.statusCode, statusCode: error.output.statusCode,
}); });
} }
return response.internalError({ body: error }); throw error;
} }
}; };
}; };

View file

@ -147,8 +147,8 @@ describe('Retrieve ES Fields', () => {
callAsCurrentUserMock.mockRejectedValueOnce(new Error('Index not found')); callAsCurrentUserMock.mockRejectedValueOnce(new Error('Index not found'));
const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); await expect(
routeHandler(mockRouteContext, request, kibanaResponseFactory)
expect(response.status).toBe(500); ).rejects.toThrowError('Index not found');
}); });
}); });

View file

@ -55,7 +55,7 @@ export const registerCreateRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
} }
@ -71,7 +71,7 @@ export const registerCreateRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -41,7 +41,7 @@ export const registerDeleteRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -37,7 +37,7 @@ export const registerFetchRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -48,7 +48,7 @@ export const registerGetRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -40,7 +40,7 @@ export const registerPauseRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -40,7 +40,7 @@ export const registerResumeRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -54,7 +54,7 @@ export const registerUpdateRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -64,7 +64,7 @@ export const registerPermissionsRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -36,7 +36,7 @@ export const registerStatsRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -59,7 +59,7 @@ export const registerCreateRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -56,7 +56,7 @@ export const registerFetchRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -72,7 +72,7 @@ export const registerGetRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export const registerPauseRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -38,7 +38,7 @@ export const registerResumeRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -39,7 +39,7 @@ export const registerUnfollowRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); return response.customError({ statusCode: 500, body: err });
}; };
await Promise.all( await Promise.all(

View file

@ -87,7 +87,7 @@ export const registerUpdateRoute = ({
return response.customError(formatEsError(err)); return response.customError(formatEsError(err));
} }
// Case: default // Case: default
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -7,7 +7,7 @@
import { MockRouter, mockLogger, mockDependencies } from '../../__mocks__'; import { MockRouter, mockLogger, mockDependencies } from '../../__mocks__';
import { loggingSystemMock, savedObjectsServiceMock } from 'src/core/server/mocks'; import { savedObjectsServiceMock } from 'src/core/server/mocks';
jest.mock('../../collectors/lib/telemetry', () => ({ jest.mock('../../collectors/lib/telemetry', () => ({
incrementUICounter: jest.fn(), incrementUICounter: jest.fn(),
@ -84,17 +84,17 @@ describe('Enterprise Search Telemetry API', () => {
it('throws an error when incrementing fails', async () => { it('throws an error when incrementing fails', async () => {
(incrementUICounter as jest.Mock).mockImplementation(jest.fn(() => Promise.reject('Failed'))); (incrementUICounter as jest.Mock).mockImplementation(jest.fn(() => Promise.reject('Failed')));
await mockRouter.callRoute({ await expect(
body: { mockRouter.callRoute({
product: 'enterprise_search', body: {
action: 'error', product: 'enterprise_search',
metric: 'error', action: 'error',
}, metric: 'error',
}); },
})
).rejects.toEqual('Failed');
expect(incrementUICounter).toHaveBeenCalled(); expect(incrementUICounter).toHaveBeenCalled();
expect(mockLogger.error).toHaveBeenCalled();
expect(mockRouter.response.internalError).toHaveBeenCalled();
}); });
it('throws an error if the Saved Objects service is unavailable', async () => { it('throws an error if the Saved Objects service is unavailable', async () => {
@ -104,16 +104,9 @@ describe('Enterprise Search Telemetry API', () => {
getSavedObjectsService: null, getSavedObjectsService: null,
log: mockLogger, log: mockLogger,
} as any); } as any);
await mockRouter.callRoute({}); await expect(mockRouter.callRoute({})).rejects.toThrow();
expect(incrementUICounter).not.toHaveBeenCalled(); expect(incrementUICounter).not.toHaveBeenCalled();
expect(mockLogger.error).toHaveBeenCalled();
expect(mockRouter.response.internalError).toHaveBeenCalled();
expect(loggingSystemMock.collect(mockLogger).error[0][0]).toEqual(
expect.stringContaining(
'Enterprise Search UI telemetry error: Error: Could not find Saved Objects service'
)
);
}); });
describe('validates', () => { describe('validates', () => {

View file

@ -20,7 +20,7 @@ const productToTelemetryMap = {
workplace_search: WS_TELEMETRY_NAME, workplace_search: WS_TELEMETRY_NAME,
}; };
export function registerTelemetryRoute({ router, getSavedObjectsService, log }: RouteDependencies) { export function registerTelemetryRoute({ router, getSavedObjectsService }: RouteDependencies) {
router.put( router.put(
{ {
path: '/api/enterprise_search/stats', path: '/api/enterprise_search/stats',
@ -43,23 +43,16 @@ export function registerTelemetryRoute({ router, getSavedObjectsService, log }:
async (ctx, request, response) => { async (ctx, request, response) => {
const { product, action, metric } = request.body; const { product, action, metric } = request.body;
try { if (!getSavedObjectsService) throw new Error('Could not find Saved Objects service');
if (!getSavedObjectsService) throw new Error('Could not find Saved Objects service');
return response.ok({ return response.ok({
body: await incrementUICounter({ body: await incrementUICounter({
id: productToTelemetryMap[product], id: productToTelemetryMap[product],
savedObjects: getSavedObjectsService(), savedObjects: getSavedObjectsService(),
uiAction: `ui_${action}`, uiAction: `ui_${action}`,
metric, metric,
}), }),
}); });
} catch (e) {
log.error(
`Enterprise Search UI telemetry error: ${e instanceof Error ? e.stack : e.toString()}`
);
return response.internalError({ body: 'Enterprise Search UI telemetry failed' });
}
} }
); );
} }

View file

@ -76,11 +76,7 @@ export function registerExploreRoute({
} }
} }
return response.internalError({ throw error;
body: {
message: error.message,
},
});
} }
} }
) )

View file

@ -71,7 +71,7 @@ export const registerCreateRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -54,7 +54,7 @@ export function registerGetAllRoute({ router, license, lib: { isEsError } }: Rou
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );
@ -94,7 +94,7 @@ export function registerGetAllRoute({ router, license, lib: { isEsError } }: Rou
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -64,7 +64,7 @@ export const registerPrivilegesRoute = ({ license, router, config }: RouteDepend
return res.ok({ body: privilegesResult }); return res.ok({ body: privilegesResult });
} catch (e) { } catch (e) {
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -55,7 +55,7 @@ export const registerUpdateRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerClearCacheRoute({ router, license, lib }: RouteDependenc
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerCloseRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerDeleteRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerFlushRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -45,7 +45,7 @@ export function registerForcemergeRoute({ router, license, lib }: RouteDependenc
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -40,7 +40,7 @@ export function registerFreezeRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -27,7 +27,7 @@ export function registerListRoute({ router, license, indexDataEnricher, lib }: R
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerOpenRoute({ router, license, lib }: RouteDependencies) {
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -38,7 +38,7 @@ export function registerRefreshRoute({ router, license, lib }: RouteDependencies
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -43,7 +43,7 @@ export function registerReloadRoute({
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -35,7 +35,7 @@ export function registerUnfreezeRoute({ router, license, lib }: RouteDependencie
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -47,7 +47,7 @@ export function registerMappingRoute({ router, license, lib }: RouteDependencies
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -48,7 +48,7 @@ export function registerLoadRoute({ router, license, lib }: RouteDependencies) {
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -46,7 +46,7 @@ export function registerUpdateRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -47,7 +47,7 @@ export function registerStatsRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -73,7 +73,7 @@ export function registerCreateRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -109,7 +109,7 @@ export function registerGetOneRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -40,7 +40,7 @@ export function registerSimulateRoute({ router, license, lib }: RouteDependencie
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -66,7 +66,7 @@ export function registerUpdateRoute({ router, license, lib }: RouteDependencies)
}); });
} }
// Case: default // Case: default
return res.internalError({ body: e }); throw e;
} }
}) })
); );

View file

@ -33,33 +33,27 @@ export const initInventoryMetaRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const { sourceId, nodeType, currentTime } = pipe(
const { sourceId, nodeType, currentTime } = pipe( InventoryMetaRequestRT.decode(request.body),
InventoryMetaRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const { configuration } = await libs.sources.getSourceConfiguration( const { configuration } = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client, requestContext.core.savedObjects.client,
sourceId sourceId
); );
const awsMetadata = await getCloudMetadata( const awsMetadata = await getCloudMetadata(
framework, framework,
requestContext, requestContext,
configuration, configuration,
nodeType, nodeType,
currentTime currentTime
); );
return response.ok({ return response.ok({
body: InventoryMetaResponseRT.encode(awsMetadata), body: InventoryMetaResponseRT.encode(awsMetadata),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -31,65 +31,59 @@ export const initValidateLogAnalysisIndicesRoute = ({ framework }: InfraBackendL
validate: { body: escapeHatch }, validate: { body: escapeHatch },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const payload = pipe(
const payload = pipe( validationIndicesRequestPayloadRT.decode(request.body),
validationIndicesRequestPayloadRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const { fields, indices } = payload.data; const { fields, indices } = payload.data;
const errors: ValidationIndicesError[] = []; const errors: ValidationIndicesError[] = [];
// Query each pattern individually, to map correctly the errors // Query each pattern individually, to map correctly the errors
await Promise.all( await Promise.all(
indices.map(async (index) => { indices.map(async (index) => {
const fieldCaps = await framework.callWithRequest(requestContext, 'fieldCaps', { const fieldCaps = await framework.callWithRequest(requestContext, 'fieldCaps', {
allow_no_indices: true, allow_no_indices: true,
fields: fields.map((field) => field.name), fields: fields.map((field) => field.name),
ignore_unavailable: true, ignore_unavailable: true,
index,
});
if (fieldCaps.indices.length === 0) {
errors.push({
error: 'INDEX_NOT_FOUND',
index, index,
}); });
return;
}
if (fieldCaps.indices.length === 0) { fields.forEach(({ name: fieldName, validTypes }) => {
const fieldMetadata = fieldCaps.fields[fieldName];
if (fieldMetadata === undefined) {
errors.push({ errors.push({
error: 'INDEX_NOT_FOUND', error: 'FIELD_NOT_FOUND',
index, index,
field: fieldName,
}); });
return; } else {
} const fieldTypes = Object.keys(fieldMetadata);
fields.forEach(({ name: fieldName, validTypes }) => { if (!fieldTypes.every((fieldType) => validTypes.includes(fieldType))) {
const fieldMetadata = fieldCaps.fields[fieldName];
if (fieldMetadata === undefined) {
errors.push({ errors.push({
error: 'FIELD_NOT_FOUND', error: `FIELD_NOT_VALID`,
index, index,
field: fieldName, field: fieldName,
}); });
} else {
const fieldTypes = Object.keys(fieldMetadata);
if (!fieldTypes.every((fieldType) => validTypes.includes(fieldType))) {
errors.push({
error: `FIELD_NOT_VALID`,
index,
field: fieldName,
});
}
} }
}); }
}) });
); })
);
return response.ok({ return response.ok({
body: validationIndicesResponsePayloadRT.encode({ data: { errors } }), body: validationIndicesResponsePayloadRT.encode({ data: { errors } }),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -33,75 +33,69 @@ export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBa
validate: { body: escapeHatch }, validate: { body: escapeHatch },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const payload = pipe(
const payload = pipe( logEntriesHighlightsRequestRT.decode(request.body),
logEntriesHighlightsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
const { startTimestamp, endTimestamp, sourceId, query, size, highlightTerms } = payload;
let entriesPerHighlightTerm;
if ('center' in payload) {
entriesPerHighlightTerm = await Promise.all(
highlightTerms.map((highlightTerm) =>
logEntries.getLogEntriesAround(requestContext, sourceId, {
startTimestamp,
endTimestamp,
query: parseFilterQuery(query),
center: payload.center,
size,
highlightTerm,
})
)
); );
} else {
const { startTimestamp, endTimestamp, sourceId, query, size, highlightTerms } = payload; let cursor: LogEntriesParams['cursor'];
if ('before' in payload) {
let entriesPerHighlightTerm; cursor = { before: payload.before };
} else if ('after' in payload) {
if ('center' in payload) { cursor = { after: payload.after };
entriesPerHighlightTerm = await Promise.all(
highlightTerms.map((highlightTerm) =>
logEntries.getLogEntriesAround(requestContext, sourceId, {
startTimestamp,
endTimestamp,
query: parseFilterQuery(query),
center: payload.center,
size,
highlightTerm,
})
)
);
} else {
let cursor: LogEntriesParams['cursor'];
if ('before' in payload) {
cursor = { before: payload.before };
} else if ('after' in payload) {
cursor = { after: payload.after };
}
entriesPerHighlightTerm = await Promise.all(
highlightTerms.map((highlightTerm) =>
logEntries.getLogEntries(requestContext, sourceId, {
startTimestamp,
endTimestamp,
query: parseFilterQuery(query),
cursor,
size,
highlightTerm,
})
)
);
} }
return response.ok({ entriesPerHighlightTerm = await Promise.all(
body: logEntriesHighlightsResponseRT.encode({ highlightTerms.map((highlightTerm) =>
data: entriesPerHighlightTerm.map(({ entries }) => { logEntries.getLogEntries(requestContext, sourceId, {
if (entries.length > 0) { startTimestamp,
return { endTimestamp,
entries, query: parseFilterQuery(query),
topCursor: entries[0].cursor, cursor,
bottomCursor: entries[entries.length - 1].cursor, size,
}; highlightTerm,
} else { })
return { )
entries, );
topCursor: null,
bottomCursor: null,
};
}
}),
}),
});
} catch (error) {
return response.internalError({
body: error.message,
});
} }
return response.ok({
body: logEntriesHighlightsResponseRT.encode({
data: entriesPerHighlightTerm.map(({ entries }) => {
if (entries.length > 0) {
return {
entries,
topCursor: entries[0].cursor,
bottomCursor: entries[entries.length - 1].cursor,
};
} else {
return {
entries,
topCursor: null,
bottomCursor: null,
};
}
}),
}),
});
} }
); );
}; };

View file

@ -33,38 +33,32 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke
validate: { body: escapeHatch }, validate: { body: escapeHatch },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const payload = pipe(
const payload = pipe( logEntriesSummaryRequestRT.decode(request.body),
logEntriesSummaryRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
); const { sourceId, startTimestamp, endTimestamp, bucketSize, query } = payload;
const { sourceId, startTimestamp, endTimestamp, bucketSize, query } = payload;
const buckets = await logEntries.getLogSummaryBucketsBetween( const buckets = await logEntries.getLogSummaryBucketsBetween(
requestContext, requestContext,
sourceId, sourceId,
startTimestamp, startTimestamp,
endTimestamp, endTimestamp,
bucketSize, bucketSize,
parseFilterQuery(query) parseFilterQuery(query)
); );
UsageCollector.countLogs(); UsageCollector.countLogs();
return response.ok({ return response.ok({
body: logEntriesSummaryResponseRT.encode({ body: logEntriesSummaryResponseRT.encode({
data: { data: {
start: startTimestamp, start: startTimestamp,
end: endTimestamp, end: endTimestamp,
buckets, buckets,
}, },
}), }),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -35,44 +35,31 @@ export const initLogEntriesSummaryHighlightsRoute = ({
validate: { body: escapeHatch }, validate: { body: escapeHatch },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const payload = pipe(
const payload = pipe( logEntriesSummaryHighlightsRequestRT.decode(request.body),
logEntriesSummaryHighlightsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
); const { sourceId, startTimestamp, endTimestamp, bucketSize, query, highlightTerms } = payload;
const {
sourceId,
startTimestamp,
endTimestamp,
bucketSize,
query,
highlightTerms,
} = payload;
const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween( const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween(
requestContext, requestContext,
sourceId, sourceId,
startTimestamp, startTimestamp,
endTimestamp, endTimestamp,
bucketSize, bucketSize,
highlightTerms, highlightTerms,
parseFilterQuery(query) parseFilterQuery(query)
); );
return response.ok({ return response.ok({
body: logEntriesSummaryHighlightsResponseRT.encode({ body: logEntriesSummaryHighlightsResponseRT.encode({
data: bucketsPerHighlightTerm.map((buckets) => ({ data: bucketsPerHighlightTerm.map((buckets) => ({
start: startTimestamp, start: startTimestamp,
end: endTimestamp, end: endTimestamp,
buckets, buckets,
})), })),
}), }),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -37,65 +37,57 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const { nodeId, nodeType, sourceId, timeRange } = pipe(
const { nodeId, nodeType, sourceId, timeRange } = pipe( InfraMetadataRequestRT.decode(request.body),
InfraMetadataRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const { configuration } = await libs.sources.getSourceConfiguration( const { configuration } = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client, requestContext.core.savedObjects.client,
sourceId sourceId
); );
const metricsMetadata = await getMetricMetadata( const metricsMetadata = await getMetricMetadata(
framework, framework,
requestContext, requestContext,
configuration, configuration,
nodeId, nodeId,
nodeType, nodeType,
timeRange timeRange
); );
const metricFeatures = pickFeatureName(metricsMetadata.buckets).map( const metricFeatures = pickFeatureName(metricsMetadata.buckets).map(nameToFeature('metrics'));
nameToFeature('metrics')
);
const info = await getNodeInfo( const info = await getNodeInfo(
framework, framework,
requestContext, requestContext,
configuration, configuration,
nodeId, nodeId,
nodeType, nodeType,
timeRange timeRange
); );
const cloudInstanceId = get(info, 'cloud.instance.id'); const cloudInstanceId = get(info, 'cloud.instance.id');
const cloudMetricsMetadata = cloudInstanceId const cloudMetricsMetadata = cloudInstanceId
? await getCloudMetricsMetadata( ? await getCloudMetricsMetadata(
framework, framework,
requestContext, requestContext,
configuration, configuration,
cloudInstanceId, cloudInstanceId,
timeRange timeRange
) )
: { buckets: [] }; : { buckets: [] };
const cloudMetricsFeatures = pickFeatureName(cloudMetricsMetadata.buckets).map( const cloudMetricsFeatures = pickFeatureName(cloudMetricsMetadata.buckets).map(
nameToFeature('metrics') nameToFeature('metrics')
); );
const id = metricsMetadata.id; const id = metricsMetadata.id;
const name = metricsMetadata.name || id; const name = metricsMetadata.name || id;
return response.ok({ return response.ok({
body: InfraMetadataRT.encode({ body: InfraMetadataRT.encode({
id, id,
name, name,
features: [...metricFeatures, ...cloudMetricsFeatures], features: [...metricFeatures, ...cloudMetricsFeatures],
info, info,
}), }),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -29,23 +29,17 @@ export const initMetricsAPIRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const options = pipe(
const options = pipe( MetricsAPIRequestRT.decode(request.body),
MetricsAPIRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const metricsApiResponse = await query(client, options); const metricsApiResponse = await query(client, options);
return response.ok({ return response.ok({
body: MetricsAPIResponseRT.encode(metricsApiResponse), body: MetricsAPIResponseRT.encode(metricsApiResponse),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -37,55 +37,49 @@ export const initMetricExplorerRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const options = pipe(
const options = pipe( metricsExplorerRequestBodyRT.decode(request.body),
metricsExplorerRequestBodyRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const interval = await findIntervalForMetrics(client, options); const interval = await findIntervalForMetrics(client, options);
const optionsWithInterval = options.forceInterval const optionsWithInterval = options.forceInterval
? options ? options
: { : {
...options, ...options,
timerange: { timerange: {
...options.timerange, ...options.timerange,
interval: interval ? `>=${interval}s` : options.timerange.interval, interval: interval ? `>=${interval}s` : options.timerange.interval,
}, },
}; };
const metricsApiOptions = convertRequestToMetricsAPIOptions(optionsWithInterval); const metricsApiOptions = convertRequestToMetricsAPIOptions(optionsWithInterval);
const metricsApiResponse = await query(client, metricsApiOptions); const metricsApiResponse = await query(client, metricsApiOptions);
const totalGroupings = await queryTotalGroupings(client, metricsApiOptions); const totalGroupings = await queryTotalGroupings(client, metricsApiOptions);
const hasGroupBy = const hasGroupBy =
Array.isArray(metricsApiOptions.groupBy) && metricsApiOptions.groupBy.length > 0; Array.isArray(metricsApiOptions.groupBy) && metricsApiOptions.groupBy.length > 0;
const pageInfo: MetricsExplorerPageInfo = { const pageInfo: MetricsExplorerPageInfo = {
total: totalGroupings, total: totalGroupings,
afterKey: null, afterKey: null,
}; };
if (metricsApiResponse.info.afterKey) { if (metricsApiResponse.info.afterKey) {
pageInfo.afterKey = metricsApiResponse.info.afterKey; pageInfo.afterKey = metricsApiResponse.info.afterKey;
}
// If we have a groupBy but there are ZERO groupings returned then we need to
// return an empty array. Otherwise we transform the series to match the current schema.
const series =
hasGroupBy && totalGroupings === 0
? []
: metricsApiResponse.series.map(transformSeries(hasGroupBy));
return response.ok({
body: metricsExplorerResponseRT.encode({ series, pageInfo }),
});
} catch (error) {
return response.internalError({
body: error.message,
});
} }
// If we have a groupBy but there are ZERO groupings returned then we need to
// return an empty array. Otherwise we transform the series to match the current schema.
const series =
hasGroupBy && totalGroupings === 0
? []
: metricsApiResponse.series.map(transformSeries(hasGroupBy));
return response.ok({
body: metricsExplorerResponseRT.encode({ series, pageInfo }),
});
} }
); );
}; };

View file

@ -34,38 +34,32 @@ export const initNodeDetailsRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const { nodeId, cloudId, nodeType, metrics, timerange, sourceId } = pipe(
const { nodeId, cloudId, nodeType, metrics, timerange, sourceId } = pipe( NodeDetailsRequestRT.decode(request.body),
NodeDetailsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
); const source = await libs.sources.getSourceConfiguration(
const source = await libs.sources.getSourceConfiguration( requestContext.core.savedObjects.client,
requestContext.core.savedObjects.client, sourceId
sourceId );
);
UsageCollector.countNode(nodeType); UsageCollector.countNode(nodeType);
const options: InfraMetricsRequestOptions = { const options: InfraMetricsRequestOptions = {
nodeIds: { nodeIds: {
nodeId, nodeId,
cloudId, cloudId,
}, },
nodeType, nodeType,
sourceConfiguration: source.configuration, sourceConfiguration: source.configuration,
metrics, metrics,
timerange, timerange,
}; };
return response.ok({ return response.ok({
body: NodeDetailsMetricDataResponseRT.encode({ body: NodeDetailsMetricDataResponseRT.encode({
metrics: await libs.metrics.getMetrics(requestContext, options, request), metrics: await libs.metrics.getMetrics(requestContext, options, request),
}), }),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -36,77 +36,71 @@ export const initOverviewRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const overviewRequest = pipe(
const overviewRequest = pipe( OverviewRequestRT.decode(request.body),
OverviewRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const source = await libs.sources.getSourceConfiguration( const source = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client, requestContext.core.savedObjects.client,
overviewRequest.sourceId overviewRequest.sourceId
); );
const inventoryModelFields = findInventoryFields('host', source.configuration.fields); const inventoryModelFields = findInventoryFields('host', source.configuration.fields);
const params = { const params = {
index: source.configuration.metricAlias, index: source.configuration.metricAlias,
body: { body: {
query: { query: {
range: { range: {
[source.configuration.fields.timestamp]: { [source.configuration.fields.timestamp]: {
gte: overviewRequest.timerange.from, gte: overviewRequest.timerange.from,
lte: overviewRequest.timerange.to, lte: overviewRequest.timerange.to,
format: 'epoch_millis', format: 'epoch_millis',
},
},
},
aggs: {
hosts: {
cardinality: {
field: inventoryModelFields.id,
},
},
cpu: {
avg: {
field: 'system.cpu.total.norm.pct',
},
},
memory: {
avg: {
field: 'system.memory.actual.used.pct',
},
}, },
}, },
}, },
}; aggs: {
hosts: {
const esResponse = await client<{}, OverviewESAggResponse>(params); cardinality: {
field: inventoryModelFields.id,
return response.ok({
body: {
stats: {
hosts: {
type: 'number',
value: esResponse.aggregations?.hosts.value ?? 0,
}, },
cpu: { },
type: 'percent', cpu: {
value: esResponse.aggregations?.cpu.value ?? 0, avg: {
field: 'system.cpu.total.norm.pct',
}, },
memory: { },
type: 'percent', memory: {
value: esResponse.aggregations?.memory.value ?? 0, avg: {
field: 'system.memory.actual.used.pct',
}, },
}, },
}, },
}); },
} catch (error) { };
return response.internalError({
body: error.message, const esResponse = await client<{}, OverviewESAggResponse>(params);
});
} return response.ok({
body: {
stats: {
hosts: {
type: 'number',
value: esResponse.aggregations?.hosts.value ?? 0,
},
cpu: {
type: 'percent',
value: esResponse.aggregations?.cpu.value ?? 0,
},
memory: {
type: 'percent',
value: esResponse.aggregations?.memory.value ?? 0,
},
},
},
});
} }
); );
}; };

View file

@ -35,23 +35,17 @@ export const initProcessListRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const options = pipe(
const options = pipe( ProcessListAPIRequestRT.decode(request.body),
ProcessListAPIRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const processListResponse = await getProcessList(client, options); const processListResponse = await getProcessList(client, options);
return response.ok({ return response.ok({
body: ProcessListAPIResponseRT.encode(processListResponse), body: ProcessListAPIResponseRT.encode(processListResponse),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
@ -64,23 +58,17 @@ export const initProcessListRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const options = pipe(
const options = pipe( ProcessListAPIChartRequestRT.decode(request.body),
ProcessListAPIChartRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const processListResponse = await getProcessListChart(client, options); const processListResponse = await getProcessListChart(client, options);
return response.ok({ return response.ok({
body: ProcessListAPIChartResponseRT.encode(processListResponse), body: ProcessListAPIChartResponseRT.encode(processListResponse),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -31,29 +31,23 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const snapshotRequest = pipe(
const snapshotRequest = pipe( SnapshotRequestRT.decode(request.body),
SnapshotRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity)
fold(throwErrors(Boom.badRequest), identity) );
);
const source = await libs.sources.getSourceConfiguration( const source = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client, requestContext.core.savedObjects.client,
snapshotRequest.sourceId snapshotRequest.sourceId
); );
UsageCollector.countNode(snapshotRequest.nodeType); UsageCollector.countNode(snapshotRequest.nodeType);
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const snapshotResponse = await getNodes(client, snapshotRequest, source); const snapshotResponse = await getNodes(client, snapshotRequest, source);
return response.ok({ return response.ok({
body: SnapshotNodeResponseRT.encode(snapshotResponse), body: SnapshotNodeResponseRT.encode(snapshotResponse),
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -44,34 +44,28 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const { type, sourceId } = request.params;
const { type, sourceId } = request.params;
const [source, logIndexStatus, metricIndicesExist, indexFields] = await Promise.all([ const [source, logIndexStatus, metricIndicesExist, indexFields] = await Promise.all([
libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId), libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId),
libs.sourceStatus.getLogIndexStatus(requestContext, sourceId), libs.sourceStatus.getLogIndexStatus(requestContext, sourceId),
libs.sourceStatus.hasMetricIndices(requestContext, sourceId), libs.sourceStatus.hasMetricIndices(requestContext, sourceId),
libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType(type)), libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType(type)),
]); ]);
if (!source) { if (!source) {
return response.notFound(); return response.notFound();
}
const status: InfraSourceStatus = {
logIndicesExist: logIndexStatus !== 'missing',
metricIndicesExist,
indexFields,
};
return response.ok({
body: SourceResponseRuntimeType.encode({ source: { ...source, status } }),
});
} catch (error) {
return response.internalError({
body: error.message,
});
} }
const status: InfraSourceStatus = {
logIndicesExist: logIndexStatus !== 'missing',
metricIndicesExist,
indexFields,
};
return response.ok({
body: SourceResponseRuntimeType.encode({ source: { ...source, status } }),
});
} }
); );
@ -169,26 +163,20 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
}, },
}, },
async (requestContext, request, response) => { async (requestContext, request, response) => {
try { const { type, sourceId } = request.params;
const { type, sourceId } = request.params;
const client = createSearchClient(requestContext, framework); const client = createSearchClient(requestContext, framework);
const source = await libs.sources.getSourceConfiguration( const source = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client, requestContext.core.savedObjects.client,
sourceId sourceId
); );
const indexPattern = const indexPattern =
type === 'metrics' ? source.configuration.metricAlias : source.configuration.logAlias; type === 'metrics' ? source.configuration.metricAlias : source.configuration.logAlias;
const results = await hasData(indexPattern, client); const results = await hasData(indexPattern, client);
return response.ok({ return response.ok({
body: { hasData: results }, body: { hasData: results },
}); });
} catch (error) {
return response.internalError({
body: error.message,
});
}
} }
); );
}; };

View file

@ -83,7 +83,7 @@ export const registerCreateRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -51,7 +51,7 @@ export const registerDocumentsRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -44,7 +44,7 @@ export const registerGetRoutes = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );
@ -78,7 +78,7 @@ export const registerGetRoutes = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -44,28 +44,24 @@ export const registerPrivilegesRoute = ({ license, router, config }: RouteDepend
}, },
} = ctx; } = ctx;
try { const { has_all_requested: hasAllPrivileges, cluster } = await client.callAsCurrentUser(
const { has_all_requested: hasAllPrivileges, cluster } = await client.callAsCurrentUser( 'transport.request',
'transport.request', {
{ path: '/_security/user/_has_privileges',
path: '/_security/user/_has_privileges', method: 'POST',
method: 'POST', body: {
body: { cluster: APP_CLUSTER_REQUIRED_PRIVILEGES,
cluster: APP_CLUSTER_REQUIRED_PRIVILEGES, },
},
}
);
if (!hasAllPrivileges) {
privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster);
} }
);
privilegesResult.hasAllPrivileges = hasAllPrivileges; if (!hasAllPrivileges) {
privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster);
return res.ok({ body: privilegesResult });
} catch (e) {
return res.internalError({ body: e });
} }
privilegesResult.hasAllPrivileges = hasAllPrivileges;
return res.ok({ body: privilegesResult });
}) })
); );
}; };

View file

@ -52,7 +52,7 @@ export const registerSimulateRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -65,7 +65,7 @@ export const registerUpdateRoute = ({
}); });
} }
return res.internalError({ body: error }); throw error;
} }
}) })
); );

View file

@ -77,11 +77,9 @@ export async function existingFieldsRoute(setup: CoreSetup<PluginStartContract>,
if (e.output.statusCode === 404) { if (e.output.statusCode === 404) {
return res.notFound({ body: e.output.payload.message }); return res.notFound({ body: e.output.payload.message });
} }
return res.internalError({ body: e.output.payload.message }); throw new Error(e.output.payload.message);
} else { } else {
return res.internalError({ throw e;
body: Boom.internal(e.message || e.name),
});
} }
} }
} }

View file

@ -5,7 +5,6 @@
* 2.0. * 2.0.
*/ */
import Boom from '@hapi/boom';
import { errors } from '@elastic/elasticsearch'; import { errors } from '@elastic/elasticsearch';
import DateMath from '@elastic/datemath'; import DateMath from '@elastic/datemath';
import { schema } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema';
@ -111,11 +110,9 @@ export async function initFieldsRoute(setup: CoreSetup<PluginStartContract>) {
if (e.output.statusCode === 404) { if (e.output.statusCode === 404) {
return res.notFound(); return res.notFound();
} }
return res.internalError(e.output.message); throw new Error(e.output.message);
} else { } else {
return res.internalError({ throw e;
body: Boom.internal(e.message || e.name),
});
} }
} }
} }

View file

@ -5,7 +5,6 @@
* 2.0. * 2.0.
*/ */
import Boom from '@hapi/boom';
import { errors } from '@elastic/elasticsearch'; import { errors } from '@elastic/elasticsearch';
import { CoreSetup } from 'src/core/server'; import { CoreSetup } from 'src/core/server';
import { schema } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema';
@ -84,11 +83,9 @@ export async function initLensUsageRoute(setup: CoreSetup<PluginStartContract>)
if (e.output.statusCode === 404) { if (e.output.statusCode === 404) {
return res.notFound(); return res.notFound();
} }
return res.internalError(e.output.message); throw new Error(e.output.message);
} else { } else {
return res.internalError({ throw e;
body: Boom.internal(e.message || e.name),
});
} }
} }
} }

View file

@ -23,18 +23,14 @@ export function registerLicenseRoute({ router, plugins: { licensing } }: RouteDe
}, },
async (ctx, req, res) => { async (ctx, req, res) => {
const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client;
try { return res.ok({
return res.ok({ body: await putLicense({
body: await putLicense({ acknowledge: Boolean(req.query.acknowledge),
acknowledge: Boolean(req.query.acknowledge), callAsCurrentUser,
callAsCurrentUser, licensing,
licensing, license: req.body,
license: req.body, }),
}), });
});
} catch (e) {
return res.internalError({ body: e });
}
} }
); );
} }

View file

@ -16,12 +16,8 @@ export function registerPermissionsRoute({
router.post({ path: addBasePath('/permissions'), validate: false }, async (ctx, req, res) => { router.post({ path: addBasePath('/permissions'), validate: false }, async (ctx, req, res) => {
const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client;
try { return res.ok({
return res.ok({ body: await getPermissions({ callAsCurrentUser, isSecurityEnabled }),
body: await getPermissions({ callAsCurrentUser, isSecurityEnabled }), });
});
} catch (e) {
return res.internalError({ body: e });
}
}); });
} }

View file

@ -18,17 +18,13 @@ export function registerStartBasicRoute({ router, plugins: { licensing } }: Rout
}, },
async (ctx, req, res) => { async (ctx, req, res) => {
const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client;
try { return res.ok({
return res.ok({ body: await startBasic({
body: await startBasic({ acknowledge: Boolean(req.query.acknowledge),
acknowledge: Boolean(req.query.acknowledge), callAsCurrentUser,
callAsCurrentUser, licensing,
licensing, }),
}), });
});
} catch (e) {
return res.internalError({ body: e });
}
} }
); );
} }

View file

@ -12,21 +12,13 @@ import { addBasePath } from '../../helpers';
export function registerStartTrialRoutes({ router, plugins: { licensing } }: RouteDependencies) { export function registerStartTrialRoutes({ router, plugins: { licensing } }: RouteDependencies) {
router.get({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { router.get({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => {
const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client;
try { return res.ok({ body: await canStartTrial(callAsCurrentUser) });
return res.ok({ body: await canStartTrial(callAsCurrentUser) });
} catch (e) {
return res.internalError({ body: e });
}
}); });
router.post({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { router.post({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => {
const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client;
try { return res.ok({
return res.ok({ body: await startTrial({ callAsCurrentUser, licensing }),
body: await startTrial({ callAsCurrentUser, licensing }), });
});
} catch (e) {
return res.internalError({ body: e });
}
}); });
} }

View file

@ -29,7 +29,7 @@ export function registerClusterLoadRoute(router: LogstashPluginRouter) {
if (err.status === 403) { if (err.status === 403) {
return response.ok(); return response.ok();
} }
return response.internalError(); throw err;
} }
}) })
); );

View file

@ -372,7 +372,7 @@ export class MonitoringPlugin
if (Boom.isBoom(err) || statusCode !== 500) { if (Boom.isBoom(err) || statusCode !== 500) {
return res.customError({ statusCode, body: err }); return res.customError({ statusCode, body: err });
} }
return res.internalError(wrapError(err)); throw wrapError(err).body;
} }
}; };

View file

@ -88,7 +88,7 @@ export const register = (deps: RouteDependencies): void => {
if (isEsError(error)) { if (isEsError(error)) {
return response.customError({ statusCode: error.statusCode, body: error }); return response.customError({ statusCode: error.statusCode, body: error });
} }
return response.internalError({ body: error }); throw error;
} }
}; };
deps.router.post( deps.router.post(

View file

@ -95,7 +95,7 @@ export const register = (deps: RouteDependencies): void => {
if (isEsError(error)) { if (isEsError(error)) {
return response.customError({ statusCode: error.statusCode, body: error }); return response.customError({ statusCode: error.statusCode, body: error });
} }
return response.internalError({ body: error }); throw error;
} }
}; };
@ -132,7 +132,7 @@ export const register = (deps: RouteDependencies): void => {
if (isEsError(error)) { if (isEsError(error)) {
return response.customError({ statusCode: error.statusCode, body: error }); return response.customError({ statusCode: error.statusCode, body: error });
} }
return response.internalError({ body: error }); throw error;
} }
}; };

View file

@ -78,10 +78,16 @@ describe('GET remote clusters', () => {
const mockContext = xpackMocks.createRequestHandlerContext(); const mockContext = xpackMocks.createRequestHandlerContext();
mockContext.core.elasticsearch.legacy.client = mockScopedClusterClient; mockContext.core.elasticsearch.legacy.client = mockScopedClusterClient;
const response = await handler(mockContext, mockRequest, kibanaResponseFactory); if (asserts.statusCode === 500) {
await expect(handler(mockContext, mockRequest, kibanaResponseFactory)).rejects.toThrowError(
asserts.result as Error
);
} else {
const response = await handler(mockContext, mockRequest, kibanaResponseFactory);
expect(response.status).toBe(asserts.statusCode); expect(response.status).toBe(asserts.statusCode);
expect(response.payload).toEqual(asserts.result); expect(response.payload).toEqual(asserts.result);
}
if (Array.isArray(asserts.apiArguments)) { if (Array.isArray(asserts.apiArguments)) {
for (const apiArguments of asserts.apiArguments) { for (const apiArguments of asserts.apiArguments) {

View file

@ -63,7 +63,7 @@ export const register = (deps: RouteDependencies): void => {
if (isEsError(error)) { if (isEsError(error)) {
return response.customError({ statusCode: error.statusCode, body: error }); return response.customError({ statusCode: error.statusCode, body: error });
} }
return response.internalError({ body: error }); throw error;
} }
}; };

View file

@ -100,7 +100,7 @@ export const register = (deps: RouteDependencies): void => {
if (isEsError(error)) { if (isEsError(error)) {
return response.customError({ statusCode: error.statusCode, body: error }); return response.customError({ statusCode: error.statusCode, body: error });
} }
return response.internalError({ body: error }); throw error;
} }
}; };

View file

@ -34,7 +34,7 @@ export const registerGetRoute = ({
if (isEsError(err)) { if (isEsError(err)) {
return response.customError({ statusCode: err.statusCode, body: err }); return response.customError({ statusCode: err.statusCode, body: err });
} }
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -136,7 +136,7 @@ export const registerValidateIndexPatternRoute = ({
return response.customError({ statusCode: err.statusCode, body: err }); return response.customError({ statusCode: err.statusCode, body: err });
} }
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -43,7 +43,7 @@ export const registerCreateRoute = ({
if (isEsError(err)) { if (isEsError(err)) {
return response.customError({ statusCode: err.statusCode, body: err }); return response.customError({ statusCode: err.statusCode, body: err });
} }
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -45,7 +45,7 @@ export const registerDeleteRoute = ({
if (isEsError(err)) { if (isEsError(err)) {
return response.customError({ statusCode: err.statusCode, body: err }); return response.customError({ statusCode: err.statusCode, body: err });
} }
return response.internalError({ body: err }); throw err;
} }
}) })
); );

View file

@ -26,7 +26,7 @@ export const registerGetRoute = ({
if (isEsError(err)) { if (isEsError(err)) {
return response.customError({ statusCode: err.statusCode, body: err }); return response.customError({ statusCode: err.statusCode, body: err });
} }
return response.internalError({ body: err }); throw err;
} }
}) })
); );

Some files were not shown because too many files have changed in this diff Show more