🌊 Streams - Better error handling (#211197)

In a bunch of places we would directly show `error.message` in toasts.
This is not always the right value, because the actual error is
sometimes wrapped in an HttpError. At some places we would already
unpack this correctly using a helper function - I made sure it's used
everywhere.

One example where this can be tested is when trying to map a child in an
incompatible way - let's say a field is mapped as long in
`logs.child.subchild`, then the user tries to map the same field as
keyword in `logs.child`. Previously it would just say "BadRequest", now
it says:
<img width="378" alt="Screenshot 2025-02-14 at 15 02 53"
src="https://github.com/user-attachments/assets/0abb51db-2bac-407e-bb51-beb74b3f9adb"
/>
This commit is contained in:
Joe Reuter 2025-02-14 17:17:06 +01:00 committed by GitHub
parent 7e498881d8
commit 0a50f776eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 12 additions and 7 deletions

View file

@ -83,7 +83,7 @@ const SamplePreviewTableContent = ({
}
if ((value && value.status === 'failure') || error) {
const formattedError = getFormattedError(error);
const formattedError = error && getFormattedError(error);
return (
<EuiCallOut
color="danger"

View file

@ -18,6 +18,7 @@ import { useStreamsAppFetch } from '../../../hooks/use_streams_app_fetch';
import { useKibana } from '../../../hooks/use_kibana';
import { SchemaField, isSchemaFieldTyped } from '../types';
import { convertToFieldDefinitionConfig } from '../utils';
import { getFormattedError } from '../../../util/errors';
export const useSchemaFields = ({
definition,
@ -143,7 +144,7 @@ export const useSchemaFields = ({
defaultMessage: 'Something went wrong editing the {field} field',
values: { field: field.name },
}),
toastMessage: error.body.message,
toastMessage: getFormattedError(error).message,
toastLifeTimeMs: 5000,
});
}
@ -191,7 +192,7 @@ export const useSchemaFields = ({
defaultMessage: 'Something went wrong unmapping the {field} field',
values: { field: fieldName },
}),
toastMessage: error.message,
toastMessage: getFormattedError(error).message,
toastLifeTimeMs: 5000,
});
}

View file

@ -27,6 +27,7 @@ import { useKibana } from '../../hooks/use_kibana';
import { EditLifecycleModal, LifecycleEditAction } from './modal';
import { RetentionSummary } from './summary';
import { RetentionMetadata } from './metadata';
import { getFormattedError } from '../../util/errors';
function useLifecycleState({
definition,
@ -156,7 +157,7 @@ export function StreamDetailLifecycle({
title: i18n.translate('xpack.streams.streamDetailLifecycle.failed', {
defaultMessage: 'Failed to update lifecycle',
}),
toastMessage: 'body' in error ? error.body.message : error.message,
toastMessage: getFormattedError(error).message,
});
} finally {
setUpdateInProgress(false);

View file

@ -57,6 +57,7 @@ import { useBoolean } from '@kbn/react-hooks';
import useToggle from 'react-use/lib/useToggle';
import { useStreamsAppRouter } from '../../hooks/use_streams_app_router';
import { useWiredStreams } from '../../hooks/use_wired_streams';
import { getFormattedError } from '../../util/errors';
export type LifecycleEditAction = 'none' | 'dsl' | 'ilm' | 'inherit';
@ -297,7 +298,7 @@ function IlmModal({
setPolicies(policyOptions);
})
.catch((error) => {
setErrorMessage('body' in error ? error.body.message : error.message);
setErrorMessage(getFormattedError(error).message);
})
.finally(() => setIsLoading(false));

View file

@ -15,6 +15,7 @@ import { useKibana } from '../../hooks/use_kibana';
import { useStreamsAppRouter } from '../../hooks/use_streams_app_router';
import { emptyEqualsToAlways } from '../../util/condition';
import { useRoutingState } from './hooks/routing_state';
import { getFormattedError } from '../../util/errors';
export function ControlBar({
definition,
@ -158,7 +159,7 @@ export function ControlBar({
title: i18n.translate('xpack.streams.failedToSave', {
defaultMessage: 'Failed to save',
}),
toastMessage: 'body' in error ? error.body.message : error.message,
toastMessage: getFormattedError(error).message,
});
routingAppState.setLastDisplayedToast(toast);
}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
export const getFormattedError = (error?: Error) => {
export const getFormattedError = (error: Error) => {
if (
error &&
'body' in error &&
@ -16,4 +16,5 @@ export const getFormattedError = (error?: Error) => {
) {
return new Error(error.body.message);
}
return error;
};