Skip to content

Commit

Permalink
[InfraUI] Fix / add context to Metrics error (elastic#30383) (elastic…
Browse files Browse the repository at this point in the history
…#31114)

* Add a custom and specific InvalidNode Error so that more helpful information can be displayed on the Metrics page

Add a custom error for an invalid node check

Add a component for displaying help when using an invalid node

Throw the specific error from kibana_metrics_adapter

Add an enum for specific error codes

Look for and handle invalid node error in metrics/index

Amend container to pass Error instance

Add source configuration flyout to metrics/index to facilitate change source config button

* Add explicit type for err parameter

* Remove i18n injection, use FormattedMessage component

* Stylistic index changes

* Move Error typings to common
  • Loading branch information
Kerry350 authored Feb 14, 2019
1 parent 0dd35d7 commit 08054ec
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 5 deletions.
7 changes: 7 additions & 0 deletions x-pack/plugins/infra/common/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export * from './metrics';
9 changes: 9 additions & 0 deletions x-pack/plugins/infra/common/errors/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export enum InfraMetricsErrorCodes {
invalid_node = 'METRICS_INVALID_NODE',
}
76 changes: 76 additions & 0 deletions x-pack/plugins/infra/public/components/metrics/invalid_node.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import styled from 'styled-components';
import { WithSourceConfigurationFlyoutState } from '../../components/source_configuration/source_configuration_flyout_state';
import { WithKibanaChrome } from '../../containers/with_kibana_chrome';

interface InvalidNodeErrorProps {
nodeName: string;
}

export const InvalidNodeError: React.SFC<InvalidNodeErrorProps> = ({ nodeName }) => (
<WithKibanaChrome>
{({ basePath }) => (
<CenteredEmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.infra.metrics.invalidNodeErrorTitle"
defaultMessage="Looks like {nodeName} isn't collecting any metrics data"
values={{
nodeName,
}}
/>
</h2>
}
body={
<p>
<FormattedMessage
id="xpack.infra.metrics.invalidNodeErrorDescription"
defaultMessage="Double check your configuration"
/>
</p>
}
actions={
<EuiFlexGroup>
<EuiFlexItem>
<EuiButton
href={`${basePath}/app/kibana#/home/tutorial_directory/metrics`}
color="primary"
fill
>
<FormattedMessage
id="xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel"
defaultMessage="View setup instructions"
/>
</EuiButton>
</EuiFlexItem>
<EuiFlexItem>
<WithSourceConfigurationFlyoutState>
{({ enable }) => (
<EuiButton color="primary" onClick={enable}>
<FormattedMessage
id="xpack.infra.configureSourceActionLabel"
defaultMessage="Change source configuration"
/>
</EuiButton>
)}
</WithSourceConfigurationFlyoutState>
</EuiFlexItem>
</EuiFlexGroup>
}
/>
)}
</WithKibanaChrome>
);

const CenteredEmptyPrompt = styled(EuiEmptyPrompt)`
align-self: center;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ApolloError } from 'apollo-client';
import React from 'react';
import { Query } from 'react-apollo';
import {
Expand All @@ -18,7 +18,7 @@ import { metricsQuery } from './metrics.gql_query';

interface WithMetricsArgs {
metrics: InfraMetricData[];
error?: string | undefined;
error?: ApolloError | undefined;
loading: boolean;
refetch: () => void;
}
Expand Down Expand Up @@ -63,7 +63,7 @@ export const WithMetrics = ({
{({ data, error, loading, refetch }) => {
return children({
metrics: filterOnlyInfraMetricData(data && data.source && data.source.metrics),
error: error && error.message,
error,
loading,
refetch,
});
Expand Down
16 changes: 15 additions & 1 deletion x-pack/plugins/infra/public/pages/metrics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ import {
EuiTitle,
} from '@elastic/eui';
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
import { GraphQLFormattedError } from 'graphql';
import React from 'react';
import styled, { withTheme } from 'styled-components';

import { InfraMetricsErrorCodes } from '../../../common/errors';
import { AutoSizer } from '../../components/auto_sizer';
import { Header } from '../../components/header';
import { Metrics } from '../../components/metrics';
import { InvalidNodeError } from '../../components/metrics/invalid_node';
import { MetricsSideNav } from '../../components/metrics/side_nav';
import { MetricsTimeControls } from '../../components/metrics/time_controls';
import { ColumnarPage, PageContent } from '../../components/page';
import { SourceConfigurationFlyout } from '../../components/source_configuration';
import { WithMetadata } from '../../containers/metadata/with_metadata';
import { WithMetrics } from '../../containers/metrics/with_metrics';
import {
Expand Down Expand Up @@ -113,6 +117,7 @@ export const MetricDetail = withTheme(
return (
<ColumnarPage>
<Header breadcrumbs={breadcrumbs} />
<SourceConfigurationFlyout />
<WithMetricsTimeUrlState />
<DetailPageContent>
<WithMetrics
Expand All @@ -124,7 +129,16 @@ export const MetricDetail = withTheme(
>
{({ metrics, error, loading, refetch }) => {
if (error) {
return <ErrorPageBody message={error} />;
const invalidNodeError = error.graphQLErrors.some(
(err: GraphQLFormattedError) =>
err.code === InfraMetricsErrorCodes.invalid_node
);

if (invalidNodeError) {
return <InvalidNodeError nodeName={name} />;
}

return <ErrorPageBody message={error.message} />;
}
return (
<EuiPage style={{ flex: '1 0 auto' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { InfraMetric, InfraMetricData, InfraNodeType } from '../../../graphql/ty
import { InfraBackendFrameworkAdapter, InfraFrameworkRequest } from '../framework';
import { InfraMetricsAdapter, InfraMetricsRequestOptions } from './adapter_types';
import { checkValidNode } from './lib/check_valid_node';
import { InvalidNodeError } from './lib/errors';
import { metricModels } from './models';

export class KibanaMetricsAdapter implements InfraMetricsAdapter {
Expand Down Expand Up @@ -45,7 +46,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {

const validNode = await checkValidNode(search, indexPattern, nodeField, options.nodeId);
if (!validNode) {
throw new Error(
throw new InvalidNodeError(
i18n.translate('xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage', {
defaultMessage: '{nodeId} does not exist.',
values: {
Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/infra/server/lib/adapters/metrics/lib/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ApolloError } from 'apollo-server-errors';
import { InfraMetricsErrorCodes } from '../../../../../common/errors';

export class InvalidNodeError extends ApolloError {
constructor(message: string) {
super(message, InfraMetricsErrorCodes.invalid_node);
Object.defineProperty(this, 'name', { value: 'InvalidNodeError' });
}
}

0 comments on commit 08054ec

Please sign in to comment.