Skip to content

Commit

Permalink
better error messages on the UX
Browse files Browse the repository at this point in the history
  • Loading branch information
ashokaditya committed Oct 24, 2024
1 parent 4c8f844 commit 7ca637b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const DataUsageMetrics = () => {
selectedDataStreams: dataStreamsFromUrl,
options: {
enabled: true,
retry: false,
},
});

Expand Down
12 changes: 6 additions & 6 deletions x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ export const useGetDataUsageDataStreams = ({
...options,
keepPreviousData: true,
queryFn: async () => {
const dataStreamsResponse = await http.get<GetDataUsageDataStreamsResponse>(
DATA_USAGE_DATA_STREAMS_API_ROUTE,
{
const dataStreamsResponse = await http
.get<GetDataUsageDataStreamsResponse>(DATA_USAGE_DATA_STREAMS_API_ROUTE, {
version: '1',
// query: {},
}
);
})
.catch((error) => {
throw error.body;
});

const augmentedDataStreamsBasedOnSelectedItems = dataStreamsResponse.reduce<{
selected: GetDataUsageDataStreamsResponse;
Expand Down
24 changes: 14 additions & 10 deletions x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ export const useGetDataUsageMetrics = (
...options,
keepPreviousData: true,
queryFn: async ({ signal }) => {
return http.post<UsageMetricsResponseSchemaBody>(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<UsageMetricsResponseSchemaBody>(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;
});
},
});
};
8 changes: 8 additions & 0 deletions x-pack/plugins/data_usage/server/routes/error_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand All @@ -31,6 +32,13 @@ export const errorHandler = <E extends Error>(
});
}

if (error instanceof AutoOpsError) {
return res.customError({
statusCode: 503,
body: error,
});
}

if (error instanceof NotFoundError) {
return res.notFound({ body: error });
}
Expand Down
26 changes: 13 additions & 13 deletions x-pack/plugins/data_usage/server/services/autoops_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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(
Expand Down Expand Up @@ -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));
Expand All @@ -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}`,
{
Expand All @@ -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;
}

Expand Down
10 changes: 10 additions & 0 deletions x-pack/plugins/data_usage/server/services/errors.ts
Original file line number Diff line number Diff line change
@@ -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 {}
24 changes: 17 additions & 7 deletions x-pack/plugins/data_usage/server/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
}

0 comments on commit 7ca637b

Please sign in to comment.