From 7ca637b0051319411a28d34eb177aeaf2510e7d7 Mon Sep 17 00:00:00 2001 From: Ashokaditya Date: Mon, 21 Oct 2024 14:53:21 +0200 Subject: [PATCH] better error messages on the UX --- .../app/components/data_usage_metrics.tsx | 1 + .../public/hooks/use_get_data_streams.ts | 12 ++++----- .../public/hooks/use_get_usage_metrics.ts | 24 ++++++++++------- .../data_usage/server/routes/error_handler.ts | 8 ++++++ .../data_usage/server/services/autoops_api.ts | 26 +++++++++---------- .../data_usage/server/services/errors.ts | 10 +++++++ .../data_usage/server/services/index.ts | 24 ++++++++++++----- 7 files changed, 69 insertions(+), 36 deletions(-) create mode 100644 x-pack/plugins/data_usage/server/services/errors.ts diff --git a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx index 337093ebf9c18..929ebf7a02490 100644 --- a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx +++ b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx @@ -52,6 +52,7 @@ export const DataUsageMetrics = () => { selectedDataStreams: dataStreamsFromUrl, options: { enabled: true, + retry: false, }, }); diff --git a/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts b/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts index 46a448ac82b31..598acca3c1faf 100644 --- a/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts +++ b/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts @@ -38,13 +38,13 @@ export const useGetDataUsageDataStreams = ({ ...options, keepPreviousData: true, queryFn: async () => { - const dataStreamsResponse = await http.get( - DATA_USAGE_DATA_STREAMS_API_ROUTE, - { + const dataStreamsResponse = await http + .get(DATA_USAGE_DATA_STREAMS_API_ROUTE, { version: '1', - // query: {}, - } - ); + }) + .catch((error) => { + throw error.body; + }); const augmentedDataStreamsBasedOnSelectedItems = dataStreamsResponse.reduce<{ selected: GetDataUsageDataStreamsResponse; diff --git a/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.ts b/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.ts index 4e89a7a3f5f0e..7e7406d72b9c0 100644 --- a/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.ts +++ b/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.ts @@ -28,16 +28,20 @@ export const useGetDataUsageMetrics = ( ...options, keepPreviousData: true, queryFn: async ({ signal }) => { - return http.post(DATA_USAGE_METRICS_API_ROUTE, { - signal, - version: '1', - body: JSON.stringify({ - from: body.from, - to: body.to, - metricTypes: body.metricTypes, - dataStreams: body.dataStreams, - }), - }); + return http + .post(DATA_USAGE_METRICS_API_ROUTE, { + signal, + version: '1', + body: JSON.stringify({ + from: body.from, + to: body.to, + metricTypes: body.metricTypes, + dataStreams: body.dataStreams, + }), + }) + .catch((error) => { + throw error.body; + }); }, }); }; diff --git a/x-pack/plugins/data_usage/server/routes/error_handler.ts b/x-pack/plugins/data_usage/server/routes/error_handler.ts index 122df5e72b130..b889d12674db5 100644 --- a/x-pack/plugins/data_usage/server/routes/error_handler.ts +++ b/x-pack/plugins/data_usage/server/routes/error_handler.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/server'; import { CustomHttpRequestError } from '../utils/custom_http_request_error'; import { BaseError } from '../common/errors'; +import { AutoOpsError } from '../services/errors'; export class NotFoundError extends BaseError {} @@ -31,6 +32,13 @@ export const errorHandler = ( }); } + if (error instanceof AutoOpsError) { + return res.customError({ + statusCode: 503, + body: error, + }); + } + if (error instanceof NotFoundError) { return res.notFound({ body: error }); } diff --git a/x-pack/plugins/data_usage/server/services/autoops_api.ts b/x-pack/plugins/data_usage/server/services/autoops_api.ts index ece0ec86116f2..e5ffe24c6167a 100644 --- a/x-pack/plugins/data_usage/server/services/autoops_api.ts +++ b/x-pack/plugins/data_usage/server/services/autoops_api.ts @@ -18,7 +18,11 @@ import { } from '../../common/rest_types'; import { AppContextService } from './app_context'; import { AutoOpsConfig } from '../types'; +import { AutoOpsError } from './errors'; +const AGENT_CREATION_FAILED_ERROR = 'AutoOps API could not create the autoops agent'; +const AUTO_OPS_AGENT_CREATION_PREFIX = '[AutoOps API] Creating autoops agent failed'; +const AUTO_OPS_MISSING_CONFIG_ERROR = 'Missing autoops configuration'; export class AutoOpsAPIService { constructor(private appContextService: AppContextService) {} public async autoOpsUsageMetricsAPI(requestBody: UsageMetricsRequestBody) { @@ -34,8 +38,8 @@ export class AutoOpsAPIService { const autoopsConfig = this.appContextService.getConfig()?.autoops; if (!autoopsConfig) { - logger.error('[AutoOps API] Missing autoops configuration', errorMetadata); - throw new Error('missing autoops configuration'); + logger.error(`[AutoOps API] ${AUTO_OPS_MISSING_CONFIG_ERROR}`, errorMetadata); + throw new AutoOpsError(AUTO_OPS_MISSING_CONFIG_ERROR); } logger.debug( @@ -86,7 +90,7 @@ export class AutoOpsAPIService { (error: Error | AxiosError) => { if (!axios.isAxiosError(error)) { logger.error( - `[AutoOps API] Creating autoops failed with an error ${error} ${requestConfigDebugStatus}`, + `${AUTO_OPS_AGENT_CREATION_PREFIX} with an error ${error} ${requestConfigDebugStatus}`, errorMetadataWithRequestConfig ); throw new Error(withRequestIdMessage(error.message)); @@ -97,7 +101,7 @@ export class AutoOpsAPIService { if (error.response) { // The request was made and the server responded with a status code and error data logger.error( - `[AutoOps API] Creating autoops failed because the AutoOps API responding with a status code that falls out of the range of 2xx: ${JSON.stringify( + `${AUTO_OPS_AGENT_CREATION_PREFIX} because the AutoOps API responded with a status code that falls out of the range of 2xx: ${JSON.stringify( error.response.status )}} ${JSON.stringify(error.response.data)}} ${requestConfigDebugStatus}`, { @@ -111,30 +115,26 @@ export class AutoOpsAPIService { }, } ); - throw new Error( - withRequestIdMessage(`the AutoOps API could not create the autoops agent`) - ); + throw new AutoOpsError(withRequestIdMessage(AGENT_CREATION_FAILED_ERROR)); } else if (error.request) { // The request was made but no response was received logger.error( - `[AutoOps API] Creating autoops agent failed while sending the request to the AutoOps API: ${errorLogCodeCause} ${requestConfigDebugStatus}`, + `${AUTO_OPS_AGENT_CREATION_PREFIX} while sending the request to the AutoOps API: ${errorLogCodeCause} ${requestConfigDebugStatus}`, errorMetadataWithRequestConfig ); throw new Error(withRequestIdMessage(`no response received from the AutoOps API`)); } else { // Something happened in setting up the request that triggered an Error logger.error( - `[AutoOps API] Creating autoops agent failed to be created ${errorLogCodeCause} ${requestConfigDebugStatus}`, + `${AUTO_OPS_AGENT_CREATION_PREFIX} to be created ${errorLogCodeCause} ${requestConfigDebugStatus}`, errorMetadataWithRequestConfig ); - throw new Error( - withRequestIdMessage('the AutoOps API could not create the autoops agent') - ); + throw new AutoOpsError(withRequestIdMessage(AGENT_CREATION_FAILED_ERROR)); } } ); - logger.debug(`[AutoOps API] Created an autoops agent ${response}`); + logger.debug(`[AutoOps API] Successfully created an autoops agent ${response}`); return response; } diff --git a/x-pack/plugins/data_usage/server/services/errors.ts b/x-pack/plugins/data_usage/server/services/errors.ts new file mode 100644 index 0000000000000..0574e2a3c75fb --- /dev/null +++ b/x-pack/plugins/data_usage/server/services/errors.ts @@ -0,0 +1,10 @@ +/* + * 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 { BaseError } from '../common/errors'; + +export class AutoOpsError extends BaseError {} diff --git a/x-pack/plugins/data_usage/server/services/index.ts b/x-pack/plugins/data_usage/server/services/index.ts index 4026891180a78..9ccd08861a26c 100644 --- a/x-pack/plugins/data_usage/server/services/index.ts +++ b/x-pack/plugins/data_usage/server/services/index.ts @@ -4,10 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { ValidationError } from '@kbn/config-schema'; import { AppContextService } from './app_context'; import { AutoOpsAPIService } from './autoops_api'; import type { DataUsageContext } from '../types'; import { MetricTypes } from '../../common/rest_types'; +import { AutoOpsError } from './errors'; export class DataUsageService { private appContextService: AppContextService; @@ -32,12 +34,20 @@ export class DataUsageService { metricTypes: MetricTypes[]; dataStreams: string[]; }) { - const response = await this.autoOpsAPIService.autoOpsUsageMetricsAPI({ - from, - to, - metricTypes, - dataStreams, - }); - return response.data; + try { + const response = await this.autoOpsAPIService.autoOpsUsageMetricsAPI({ + from, + to, + metricTypes, + dataStreams, + }); + return response.data; + } catch (error) { + if (error instanceof ValidationError) { + throw new AutoOpsError(error.message); + } + + throw error; + } } }