From 942f5420ed3c8c30457929cda1b1491e59510d3c Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Mon, 9 Dec 2019 15:03:18 -0500 Subject: [PATCH] provide finer detail on action execution errors (#52146) resolves https://github.com/elastic/kibana/issues/52103 --- .../server/action_type_registry.test.ts | 2 +- .../actions/server/actions_client.test.ts | 2 +- .../server/builtin_action_types/email.ts | 10 +- .../server/builtin_action_types/es_index.ts | 16 ++-- .../builtin_action_types/pagerduty.test.ts | 93 ++++++++++--------- .../server/builtin_action_types/pagerduty.ts | 19 ++-- .../server/builtin_action_types/server_log.ts | 10 +- .../server/builtin_action_types/slack.ts | 62 +++++++------ .../server/builtin_action_types/webhook.ts | 55 +++++------ .../server/lib/action_executor.test.ts | 2 + .../actions/server/lib/action_executor.ts | 4 +- .../server/lib/task_runner_factory.test.ts | 7 +- .../server/lib/validate_with_schema.test.ts | 2 +- .../actions/server/routes/execute.test.ts | 4 +- x-pack/legacy/plugins/actions/server/types.ts | 2 + .../translations/translations/ja-JP.json | 16 ---- .../translations/translations/zh-CN.json | 16 ---- .../common/fixtures/plugins/alerts/index.ts | 4 +- .../actions/builtin_action_types/es_index.ts | 2 +- .../actions/builtin_action_types/pagerduty.ts | 11 +-- .../actions/builtin_action_types/slack.ts | 7 +- .../actions/builtin_action_types/webhook.ts | 5 +- 22 files changed, 157 insertions(+), 194 deletions(-) diff --git a/x-pack/legacy/plugins/actions/server/action_type_registry.test.ts b/x-pack/legacy/plugins/actions/server/action_type_registry.test.ts index b4d73cc4759d77..c0a01bc85e9169 100644 --- a/x-pack/legacy/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/legacy/plugins/actions/server/action_type_registry.test.ts @@ -18,7 +18,7 @@ const actionTypeRegistryParams = { beforeEach(() => jest.resetAllMocks()); const executor: ExecutorType = async options => { - return { status: 'ok' }; + return { status: 'ok', actionId: options.actionId }; }; describe('register()', () => { diff --git a/x-pack/legacy/plugins/actions/server/actions_client.test.ts b/x-pack/legacy/plugins/actions/server/actions_client.test.ts index 1c10d1b1a83af2..1cbf3949d20f8c 100644 --- a/x-pack/legacy/plugins/actions/server/actions_client.test.ts +++ b/x-pack/legacy/plugins/actions/server/actions_client.test.ts @@ -30,7 +30,7 @@ const actionTypeRegistryParams = { let actionsClient: ActionsClient; let actionTypeRegistry: ActionTypeRegistry; const executor: ExecutorType = async options => { - return { status: 'ok' }; + return { status: 'ok', actionId: options.actionId }; }; beforeEach(() => { diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts index a378d8a4b9b558..dd2bd328ce53fe 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts @@ -174,19 +174,17 @@ async function executor( result = await sendEmail(logger, sendEmailOptions); } catch (err) { const message = i18n.translate('xpack.actions.builtin.email.errorSendingErrorMessage', { - defaultMessage: 'error in action "{actionId}" sending email: {errorMessage}', - values: { - actionId, - errorMessage: err.message, - }, + defaultMessage: 'error sending email', }); return { status: 'error', + actionId, message, + serviceMessage: err.message, }; } - return { status: 'ok', data: result }; + return { status: 'ok', data: result, actionId }; } // utilities diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.ts index 01853ee9cb870b..0e9fe0483ee1ea 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.ts @@ -60,13 +60,11 @@ async function executor( if (config.index == null && params.index == null) { const message = i18n.translate('xpack.actions.builtin.esIndex.indexParamRequiredErrorMessage', { - defaultMessage: 'index param needs to be set because not set in config for action {actionId}', - values: { - actionId, - }, + defaultMessage: 'index param needs to be set because not set in config for action', }); return { status: 'error', + actionId, message, }; } @@ -101,17 +99,15 @@ async function executor( result = await services.callCluster('bulk', bulkParams); } catch (err) { const message = i18n.translate('xpack.actions.builtin.esIndex.errorIndexingErrorMessage', { - defaultMessage: 'error in action "{actionId}" indexing data: {errorMessage}', - values: { - actionId, - errorMessage: err.message, - }, + defaultMessage: 'error indexing documents', }); return { status: 'error', + actionId, message, + serviceMessage: err.message, }; } - return { status: 'ok', data: result }; + return { status: 'ok', data: result, actionId }; } diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts index 1d453d2bd23408..def3b7eea21d96 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts @@ -148,11 +148,12 @@ describe('execute()', () => { } `); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "data": "data-here", - "status": "ok", - } - `); + Object { + "actionId": "some-action-id", + "data": "data-here", + "status": "ok", + } + `); }); test('should succeed with maximal valid params for trigger', async () => { @@ -212,11 +213,12 @@ describe('execute()', () => { } `); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "data": "data-here", - "status": "ok", - } - `); + Object { + "actionId": "some-action-id", + "data": "data-here", + "status": "ok", + } + `); }); test('should succeed with maximal valid params for acknowledge', async () => { @@ -267,11 +269,12 @@ describe('execute()', () => { } `); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "data": "data-here", - "status": "ok", - } - `); + Object { + "actionId": "some-action-id", + "data": "data-here", + "status": "ok", + } + `); }); test('should succeed with maximal valid params for resolve', async () => { @@ -322,11 +325,12 @@ describe('execute()', () => { } `); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "data": "data-here", - "status": "ok", - } - `); + Object { + "actionId": "some-action-id", + "data": "data-here", + "status": "ok", + } + `); }); test('should fail when sendPagerdury throws', async () => { @@ -348,11 +352,13 @@ describe('execute()', () => { }; const actionResponse = await actionType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "message": "error in pagerduty action \\"some-action-id\\" posting event: doing some testing", - "status": "error", - } - `); + Object { + "actionId": "some-action-id", + "message": "error posting pagerduty event", + "serviceMessage": "doing some testing", + "status": "error", + } + `); }); test('should fail when sendPagerdury returns 429', async () => { @@ -374,12 +380,13 @@ describe('execute()', () => { }; const actionResponse = await actionType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "message": "error in pagerduty action \\"some-action-id\\" posting event: status 429, retry later", - "retry": true, - "status": "error", - } - `); + Object { + "actionId": "some-action-id", + "message": "error posting pagerduty event: http status 429, retry later", + "retry": true, + "status": "error", + } + `); }); test('should fail when sendPagerdury returns 501', async () => { @@ -401,12 +408,13 @@ describe('execute()', () => { }; const actionResponse = await actionType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "message": "error in pagerduty action \\"some-action-id\\" posting event: status 501, retry later", - "retry": true, - "status": "error", - } - `); + Object { + "actionId": "some-action-id", + "message": "error posting pagerduty event: http status 501, retry later", + "retry": true, + "status": "error", + } + `); }); test('should fail when sendPagerdury returns 418', async () => { @@ -428,10 +436,11 @@ describe('execute()', () => { }; const actionResponse = await actionType.executor(executorOptions); expect(actionResponse).toMatchInlineSnapshot(` - Object { - "message": "error in pagerduty action \\"some-action-id\\" posting event: unexpected status 418", - "status": "error", - } - `); + Object { + "actionId": "some-action-id", + "message": "error posting pagerduty event: unexpected status 418", + "status": "error", + } + `); }); }); diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.ts index ec45e298d39022..e1437b8eef5542 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.ts @@ -123,16 +123,14 @@ async function executor( response = await postPagerduty({ apiUrl, data, headers, services }); } catch (err) { const message = i18n.translate('xpack.actions.builtin.pagerduty.postingErrorMessage', { - defaultMessage: 'error in pagerduty action "{actionId}" posting event: {errorMessage}', - values: { - actionId, - errorMessage: err.message, - }, + defaultMessage: 'error posting pagerduty event', }); logger.warn(`error thrown posting pagerduty event: ${err.message}`); return { status: 'error', + actionId, message, + serviceMessage: err.message, }; } @@ -141,38 +139,37 @@ async function executor( if (response.status === 202) { return { status: 'ok', + actionId, data: response.data, }; } if (response.status === 429 || response.status >= 500) { const message = i18n.translate('xpack.actions.builtin.pagerduty.postingRetryErrorMessage', { - defaultMessage: - 'error in pagerduty action "{actionId}" posting event: status {status}, retry later', + defaultMessage: 'error posting pagerduty event: http status {status}, retry later', values: { - actionId, status: response.status, }, }); return { status: 'error', + actionId, message, retry: true, }; } const message = i18n.translate('xpack.actions.builtin.pagerduty.postingUnexpectedErrorMessage', { - defaultMessage: - 'error in pagerduty action "{actionId}" posting event: unexpected status {status}', + defaultMessage: 'error posting pagerduty event: unexpected status {status}', values: { - actionId, status: response.status, }, }); return { status: 'error', + actionId, message, }; } diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.ts index f17430b734c66b..c2af29051d8dd9 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.ts @@ -52,17 +52,15 @@ async function executor( logger[params.level](params.message); } catch (err) { const message = i18n.translate('xpack.actions.builtin.serverLog.errorLoggingErrorMessage', { - defaultMessage: 'error in action "{actionId}" logging message: {errorMessage}', - values: { - actionId, - errorMessage: err.message, - }, + defaultMessage: 'error logging message', }); return { status: 'error', message, + serviceMessage: err.message, + actionId, }; } - return { status: 'ok' }; + return { status: 'ok', actionId }; } diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.ts index 8ec569a69ff235..29b89150e3990f 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.ts @@ -69,7 +69,7 @@ async function slackExecutor( result = await webhook.send(message); } catch (err) { if (err.original == null || err.original.response == null) { - return errorResult(actionId, err.message); + return serviceErrorResult(actionId, err.message); } const { status, statusText, headers } = err.original.response; @@ -88,7 +88,17 @@ async function slackExecutor( ); } - return errorResult(actionId, `${err.message} - ${statusText}`); + const errMessage = i18n.translate( + 'xpack.actions.builtin.slack.unexpectedHttpResponseErrorMessage', + { + defaultMessage: 'unexpected http response from slack: {httpStatus} {httpStatusText}', + values: { + httpStatus: status, + httpStatusText: statusText, + }, + } + ); + return errorResult(actionId, errMessage); } if (result == null) { @@ -102,55 +112,52 @@ async function slackExecutor( } if (result.text !== 'ok') { - const errMessage = i18n.translate( - 'xpack.actions.builtin.slack.unexpectedTextResponseErrorMessage', - { - defaultMessage: 'unexpected text response from slack', - } - ); - return errorResult(actionId, errMessage); + return serviceErrorResult(actionId, result.text); } - return successResult(result); + return successResult(actionId, result); } -function successResult(data: any): ActionTypeExecutorResult { - return { status: 'ok', data }; +function successResult(actionId: string, data: any): ActionTypeExecutorResult { + return { status: 'ok', data, actionId }; } -function errorResult(id: string, message: string): ActionTypeExecutorResult { +function errorResult(actionId: string, message: string): ActionTypeExecutorResult { + return { + status: 'error', + message, + actionId, + }; +} +function serviceErrorResult(actionId: string, serviceMessage: string): ActionTypeExecutorResult { const errMessage = i18n.translate('xpack.actions.builtin.slack.errorPostingErrorMessage', { - defaultMessage: 'an error occurred in action "{id}" posting a slack message: {message}', - values: { - id, - message, - }, + defaultMessage: 'error posting slack message', }); return { status: 'error', message: errMessage, + actionId, + serviceMessage, }; } -function retryResult(id: string, message: string): ActionTypeExecutorResult { +function retryResult(actionId: string, message: string): ActionTypeExecutorResult { const errMessage = i18n.translate( 'xpack.actions.builtin.slack.errorPostingRetryLaterErrorMessage', { - defaultMessage: 'an error occurred in action "{id}" posting a slack message, retry later', - values: { - id, - }, + defaultMessage: 'error posting a slack message, retry later', } ); return { status: 'error', message: errMessage, retry: true, + actionId, }; } function retryResultSeconds( - id: string, + actionId: string, message: string, retryAfter: number ): ActionTypeExecutorResult { @@ -160,12 +167,9 @@ function retryResultSeconds( const errMessage = i18n.translate( 'xpack.actions.builtin.slack.errorPostingRetryDateErrorMessage', { - defaultMessage: - 'an error occurred in action "{id}" posting a slack message, retry at {retryString}: {message}', + defaultMessage: 'error posting a slack message, retry at {retryString}', values: { - id, retryString, - message, }, } ); @@ -173,5 +177,7 @@ function retryResultSeconds( status: 'error', message: errMessage, retry, + actionId, + serviceMessage: message, }; } diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/webhook.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/webhook.ts index b91fd86b0b6824..06fe2fb0e591c0 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/webhook.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/webhook.ts @@ -113,7 +113,7 @@ export async function executor( } = result; logger.debug(`response from webhook action "${actionId}": [HTTP ${status}] ${statusText}`); - return successResult(data); + return successResult(actionId, data); } else { const { error } = result; @@ -139,70 +139,58 @@ export async function executor( return errorResultInvalid(actionId, message); } - const message = i18n.translate('xpack.actions.builtin.webhook.unreachableRemoteWebhook', { - defaultMessage: 'Unreachable Remote Webhook, are you sure the address is correct?', - }); - logger.warn(`error on ${actionId} webhook action: ${message}`); - return errorResultUnreachable(actionId, message); + logger.warn(`error on ${actionId} webhook action: unexpected error`); + return errorResultUnexpectedError(actionId); } } // Action Executor Result w/ internationalisation -function successResult(data: any): ActionTypeExecutorResult { - return { status: 'ok', data }; +function successResult(actionId: string, data: any): ActionTypeExecutorResult { + return { status: 'ok', data, actionId }; } -function errorResultInvalid(id: string, message: string): ActionTypeExecutorResult { +function errorResultInvalid(actionId: string, serviceMessage: string): ActionTypeExecutorResult { const errMessage = i18n.translate('xpack.actions.builtin.webhook.invalidResponseErrorMessage', { - defaultMessage: - 'Invalid Response: an error occurred in webhook action "{id}" calling a remote webhook: {message}', - values: { - id, - message, - }, + defaultMessage: 'error calling webhook, invalid response', }); return { status: 'error', message: errMessage, + actionId, + serviceMessage, }; } -function errorResultUnreachable(id: string, message: string): ActionTypeExecutorResult { +function errorResultUnexpectedError(actionId: string): ActionTypeExecutorResult { const errMessage = i18n.translate('xpack.actions.builtin.webhook.unreachableErrorMessage', { - defaultMessage: - 'Unreachable Webhook: an error occurred in webhook action "{id}" calling a remote webhook: {message}', - values: { - id, - message, - }, + defaultMessage: 'error calling webhook, unexpected error', }); return { status: 'error', message: errMessage, + actionId, }; } -function retryResult(id: string, message: string): ActionTypeExecutorResult { +function retryResult(actionId: string, serviceMessage: string): ActionTypeExecutorResult { const errMessage = i18n.translate( 'xpack.actions.builtin.webhook.invalidResponseRetryLaterErrorMessage', { - defaultMessage: - 'Invalid Response: an error occurred in webhook action "{id}" calling a remote webhook, retry later', - values: { - id, - }, + defaultMessage: 'error calling webhook, retry later', } ); return { status: 'error', message: errMessage, retry: true, + actionId, + serviceMessage, }; } function retryResultSeconds( - id: string, - message: string, + actionId: string, + serviceMessage: string, retryAfter: number ): ActionTypeExecutorResult { @@ -212,12 +200,9 @@ function retryResultSeconds( const errMessage = i18n.translate( 'xpack.actions.builtin.webhook.invalidResponseRetryDateErrorMessage', { - defaultMessage: - 'Invalid Response: an error occurred in webhook action "{id}" calling a remote webhook, retry at {retryString}: {message}', + defaultMessage: 'error calling webhook, retry at {retryString}', values: { - id, retryString, - message, }, } ); @@ -225,5 +210,7 @@ function retryResultSeconds( status: 'error', message: errMessage, retry, + actionId, + serviceMessage, }; } diff --git a/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts b/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts index 5ed67ae82b0ce5..6767468509d25c 100644 --- a/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts @@ -157,6 +157,7 @@ test('throws an error when config is invalid', async () => { const result = await actionExecutor.execute(executeParams); expect(result).toEqual({ + actionId: '1', status: 'error', retry: false, message: `error validating action type config: [param1]: expected value of type [string] but got [undefined]`, @@ -188,6 +189,7 @@ test('throws an error when params is invalid', async () => { const result = await actionExecutor.execute(executeParams); expect(result).toEqual({ + actionId: '1', status: 'error', retry: false, message: `error validating action params: [param1]: expected value of type [string] but got [undefined]`, diff --git a/x-pack/legacy/plugins/actions/server/lib/action_executor.ts b/x-pack/legacy/plugins/actions/server/lib/action_executor.ts index 1afb8a8870215a..c532b76a904d5a 100644 --- a/x-pack/legacy/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/legacy/plugins/actions/server/lib/action_executor.ts @@ -91,7 +91,7 @@ export class ActionExecutor { validatedConfig = validateConfig(actionType, config); validatedSecrets = validateSecrets(actionType, secrets); } catch (err) { - return { status: 'error', message: err.message, retry: false }; + return { status: 'error', actionId, message: err.message, retry: false }; } let result: ActionTypeExecutorResult | null = null; @@ -113,7 +113,7 @@ export class ActionExecutor { logger.debug(`action executed successfully: ${actionLabel}`); // return basic response if none provided - if (result == null) return { status: 'ok' }; + if (result == null) return { status: 'ok', actionId }; return result; } diff --git a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts index a5bf42bc2cc019..41a7c17a02c5a3 100644 --- a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts @@ -94,7 +94,7 @@ test('executes the task by calling the executor with proper parameters', async ( taskInstance: mockedTaskInstance, }); - mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok' }); + mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', @@ -154,6 +154,7 @@ test('throws an error with suggested retry logic when return status is error', a }); mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'error', + actionId: '2', message: 'Error message', data: { foo: true }, retry: false, @@ -174,7 +175,7 @@ test('uses API key when provided', async () => { taskInstance: mockedTaskInstance, }); - mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok' }); + mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', @@ -217,7 +218,7 @@ test(`doesn't use API key when not provided`, async () => { factory.initialize(taskRunnerFactoryInitializerParams); const taskRunner = factory.create({ taskInstance: mockedTaskInstance }); - mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok' }); + mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', diff --git a/x-pack/legacy/plugins/actions/server/lib/validate_with_schema.test.ts b/x-pack/legacy/plugins/actions/server/lib/validate_with_schema.test.ts index 4cb28728fb4216..28122c72baf654 100644 --- a/x-pack/legacy/plugins/actions/server/lib/validate_with_schema.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/validate_with_schema.test.ts @@ -10,7 +10,7 @@ import { validateParams, validateConfig, validateSecrets } from './validate_with import { ActionType, ExecutorType } from '../types'; const executor: ExecutorType = async options => { - return { status: 'ok' }; + return { status: 'ok', actionId: options.actionId }; }; test('should validate when there are no validators', () => { diff --git a/x-pack/legacy/plugins/actions/server/routes/execute.test.ts b/x-pack/legacy/plugins/actions/server/routes/execute.test.ts index cd5b9c7c4a7e84..b0ba5a8a0f5668 100644 --- a/x-pack/legacy/plugins/actions/server/routes/execute.test.ts +++ b/x-pack/legacy/plugins/actions/server/routes/execute.test.ts @@ -31,11 +31,11 @@ it('executes an action with proper parameters', async () => { callCluster: jest.fn(), savedObjectsClient: jest.fn(), }); - mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok' }); + mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '1' }); const { payload, statusCode } = await server.inject(request); expect(statusCode).toBe(200); - expect(payload).toBe('{"status":"ok"}'); + expect(JSON.parse(payload)).toEqual({ status: 'ok', actionId: '1' }); expect(mockedActionExecutor.execute).toHaveBeenCalledWith({ actionId: '1', diff --git a/x-pack/legacy/plugins/actions/server/types.ts b/x-pack/legacy/plugins/actions/server/types.ts index 5a74241bc4829c..94b34034cd8b23 100644 --- a/x-pack/legacy/plugins/actions/server/types.ts +++ b/x-pack/legacy/plugins/actions/server/types.ts @@ -51,8 +51,10 @@ export interface FindActionResult extends ActionResult { // the result returned from an action type executor function export interface ActionTypeExecutorResult { + actionId: string; status: 'ok' | 'error'; message?: string; + serviceMessage?: string; data?: any; retry?: null | boolean | Date; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b9142c821051f2..d51332c65aa544 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12047,23 +12047,7 @@ "visTypeMarkdown.params.fontSizeLabel": "ポイント単位のベースフォントサイズです。", "xpack.actions.actionTypeRegistry.get.missingActionTypeErrorMessage": "アクションタイプ \"{id}\" は登録されていません。", "xpack.actions.actionTypeRegistry.register.duplicateActionTypeErrorMessage": "アクションタイプ \"{id}\" は既に登録されています。", - "xpack.actions.builtin.email.errorSendingErrorMessage": "アクション「{actionId}」メールの送信中にエラーが発生: {errorMessage}", - "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "アクション「{actionId}」データのインデックス中にエラーが発生: {errorMessage}", - "xpack.actions.builtin.esIndex.indexParamRequiredErrorMessage": "アクション {actionId} の構成で設定されていないため、インデックスパラメーターの設定が必要です", - "xpack.actions.builtin.pagerduty.postingErrorMessage": "PagerDuty アクション「{actionId}」イベントの投稿中にエラーが発生: {errorMessage}", - "xpack.actions.builtin.pagerduty.postingRetryErrorMessage": "PagerDuty アクション「{actionId}」イベントの投稿中にエラーが発生: ステータス {status}、後程再試行してください", - "xpack.actions.builtin.pagerduty.postingUnexpectedErrorMessage": "PagerDuty アクション「{actionId}」イベントの投稿中にエラーが発生: 予期せぬステータス {status}", - "xpack.actions.builtin.serverLog.errorLoggingErrorMessage": "アクション「{actionId}」メッセージのログ記録宙にエラーが発生: {errorMessage}", - "xpack.actions.builtin.slack.errorPostingErrorMessage": "アクション「{id}」Slack メッセージの投稿中にエラーが発生しました: {message}", - "xpack.actions.builtin.slack.errorPostingRetryDateErrorMessage": "アクション「{id}」Slack メッセージの投稿中にエラーが発生しました: {retryString} に再試行してください: {message}", - "xpack.actions.builtin.slack.errorPostingRetryLaterErrorMessage": "アクション「{id}」Slack メッセージの投稿中にエラーが発生しました。後程再試行してください", "xpack.actions.builtin.slack.unexpectedNullResponseErrorMessage": "Slack から予期せぬ null 応答", - "xpack.actions.builtin.slack.unexpectedTextResponseErrorMessage": "Slack から予期せぬテキスト応答", - "xpack.actions.builtin.webhook.invalidResponseErrorMessage": "無効な応答:Web フックアクション「{id}」リモート Web フックの呼び出し中にエラーが発生しました: {message}", - "xpack.actions.builtin.webhook.invalidResponseRetryDateErrorMessage": "無効な応答: Web フックアクション「{id}」リモート Web フックの呼び出し中にエラーが発生しました。{retryString} で後程再試行してください: {message}", - "xpack.actions.builtin.webhook.invalidResponseRetryLaterErrorMessage": "無効な応答: Web フックアクション「{id}」リモート Web フックの呼び出し中にエラーが発生しました。後程再試行してください", - "xpack.actions.builtin.webhook.unreachableErrorMessage": "到達不能な Web フック: Web フックアクション「{id}」リモート Web フックの呼び出し中にエラーが発生しました: {message}", - "xpack.actions.builtin.webhook.unreachableRemoteWebhook": "リモートウェブフックにアクセスできません。アドレスが正しいことを確認してください。", "xpack.actions.builtin.webhook.webhookConfigurationError": "Web フックアクションの構成中にエラーが発生: {message}", "xpack.actions.urlWhitelistConfigurationError": "ターゲット {field} 「{value}」は Kibana のホワイトリストに登録されていません", "xpack.advancedUiActions.customizePanelTimeRange.modal.addToPanelButtonTitle": "パネルに追加", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 109693bbb4b1b4..974467a8d20d04 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12136,23 +12136,7 @@ "visTypeMarkdown.params.fontSizeLabel": "基础字体大小(磅)", "xpack.actions.actionTypeRegistry.get.missingActionTypeErrorMessage": "未注册操作类型“{id}”。", "xpack.actions.actionTypeRegistry.register.duplicateActionTypeErrorMessage": "操作类型“{id}”已注册。", - "xpack.actions.builtin.email.errorSendingErrorMessage": "发送电子邮件时操作“{actionId}”出现错误:{errorMessage}", - "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "索引数据时操作“{actionId}”出现错误:{errorMessage}", - "xpack.actions.builtin.esIndex.indexParamRequiredErrorMessage": "需要设置索引参数,因为在操作 {actionId} 的配置中未设置", - "xpack.actions.builtin.pagerduty.postingErrorMessage": "发布事件时 pagerduty 操作“{actionId}”出现错误:{errorMessage}", - "xpack.actions.builtin.pagerduty.postingRetryErrorMessage": "发布事件时 pagerduty 操作“{actionId}”出现错误:状态 {status},请稍后重试", - "xpack.actions.builtin.pagerduty.postingUnexpectedErrorMessage": "发布事件时 pagerduty 操作“{actionId}”出现错误:异常错误 {status}", - "xpack.actions.builtin.serverLog.errorLoggingErrorMessage": "记录消息时操作“{actionId}”出现错误:{errorMessage}", - "xpack.actions.builtin.slack.errorPostingErrorMessage": "发布 slack 消息时操作“{id}”出现错误:{message}", - "xpack.actions.builtin.slack.errorPostingRetryDateErrorMessage": "发布 slack 消息时操作“{id}”出现错误,请在 {retryString} 重试:{message}", - "xpack.actions.builtin.slack.errorPostingRetryLaterErrorMessage": "发布 slack 消息时操作“{id}”出现错误,请稍后重试", "xpack.actions.builtin.slack.unexpectedNullResponseErrorMessage": "来自 slack 的异常空响应", - "xpack.actions.builtin.slack.unexpectedTextResponseErrorMessage": "来自 slack 的异常文本响应", - "xpack.actions.builtin.webhook.invalidResponseErrorMessage": "无效响应:调用远程 Webhook 时 Webhook 操作“{id}”发生错误:{message}", - "xpack.actions.builtin.webhook.invalidResponseRetryDateErrorMessage": "无效响应:调用远程 Webhook 时 Webhook 操作“{id}”发生错误,请在 {retryString} 重试:{message}", - "xpack.actions.builtin.webhook.invalidResponseRetryLaterErrorMessage": "无效响应:调用远程 Webhook 时 Webhook 操作“{id}”发生错误,请稍后重试", - "xpack.actions.builtin.webhook.unreachableErrorMessage": "Webhook无法访问:调用远程 Webhook 时 Webhook 操作“{id}”发生错误:{message}", - "xpack.actions.builtin.webhook.unreachableRemoteWebhook": "远程 Webhook 无法访问,是否确定地址正确?", "xpack.actions.builtin.webhook.webhookConfigurationError": "配置 Webhook 操作时出错:{message}", "xpack.actions.urlWhitelistConfigurationError": "目标 {field}“{value}”不在 Kibana 白名单中", "xpack.advancedUiActions.customizePanelTimeRange.modal.addToPanelButtonTitle": "添加到面板", diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts index b2e69a21218256..30b235a784c224 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts @@ -19,7 +19,7 @@ export default function(kibana: any) { id: 'test.noop', name: 'Test: Noop', async executor() { - return { status: 'ok' }; + return { status: 'ok', actionId: '' }; }, }; const indexRecordActionType: ActionType = { @@ -101,6 +101,7 @@ export default function(kibana: any) { return { status: 'error', retry: new Date(params.retryAt), + actionId: '', }; }, }; @@ -162,6 +163,7 @@ export default function(kibana: any) { }); return { status: 'ok', + actionId: '', }; }, }; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index 197ad3ff80094a..aacf0b8f87ed01 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -234,7 +234,7 @@ export default function indexTest({ getService }: FtrProviderContext) { result = response.body; expect(result.status).to.equal('error'); expect(result.message).to.eql( - `index param needs to be set because not set in config for action ${createdActionID}` + 'index param needs to be set because not set in config for action' ); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index 62c8b31209729f..54f38d2fd747e3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -121,6 +121,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { .expect(200); expect(result).to.eql({ status: 'ok', + actionId: simulatedActionId, data: { dedup_key: `action:${simulatedActionId}`, message: 'Event processed', @@ -140,9 +141,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { }) .expect(200); expect(result.status).to.equal('error'); - expect(result.message).to.match( - /error in pagerduty action .+ posting event: unexpected status 418/ - ); + expect(result.message).to.match(/error posting pagerduty event: unexpected status 418/); }); it('should handle a 429 pagerduty error', async () => { @@ -158,7 +157,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(result.status).to.equal('error'); expect(result.message).to.match( - /error in pagerduty action .+ posting event: status 429, retry later/ + /error posting pagerduty event: http status 429, retry later/ ); expect(result.retry).to.equal(true); }); @@ -175,9 +174,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.equal('error'); - expect(result.message).to.match( - /error in pagerduty action .+ posting event: status 502, retry later/ - ); + expect(result.message).to.match(/error posting pagerduty event: http status 502/); expect(result.retry).to.equal(true); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index ae1464023c0119..288eda5111a1e9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -126,7 +126,7 @@ export default function slackTest({ getService }: FtrProviderContext) { }) .expect(200); expect(result.status).to.equal('error'); - expect(result.message).to.match(/an error occurred in action .+ posting a slack message/); + expect(result.message).to.match(/unexpected http response from slack: /); }); it('should handle a 429 slack error', async () => { @@ -142,8 +142,7 @@ export default function slackTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.equal('error'); - expect(result.message).to.match(/an error occurred in action .+ posting a slack message/); - expect(result.message).to.match(/retry at/); + expect(result.message).to.match(/error posting a slack message, retry at \d\d\d\d-/); const dateRetry = new Date(result.retry).getTime(); expect(dateRetry).to.greaterThan(dateStart); @@ -161,7 +160,7 @@ export default function slackTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.equal('error'); - expect(result.message).to.match(/an error occurred in action .+ posting a slack message/); + expect(result.message).to.match(/error posting a slack message, retry later/); expect(result.retry).to.equal(true); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 53b11525d1b95a..426bbe853ca190 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -196,7 +196,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.eql('error'); - expect(result.message).to.match(/Unreachable Remote Webhook/); + expect(result.message).to.match(/error calling webhook, unexpected error/); }); it('should handle failing webhook targets', async () => { const webhookActionId = await createWebhookAction(webhookSimulatorURL); @@ -211,7 +211,8 @@ export default function webhookTest({ getService }: FtrProviderContext) { .expect(200); expect(result.status).to.eql('error'); - expect(result.message).to.match(/Bad Request/); + expect(result.message).to.match(/error calling webhook, invalid response/); + expect(result.serviceMessage).to.eql('[400] Bad Request'); }); }); }