mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
# Backport This will backport the following commits from `main` to `7.17`: - [Handle content stream errors in report pre-deletion (#173792)](https://github.com/elastic/kibana/pull/173792) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Tim Sullivan","email":"tsullivan@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-01-02T23:00:53Z","message":"Handle content stream errors in report pre-deletion (#173792)\n\nRe-addresses https://github.com/elastic/kibana/issues/171363\r\n\r\nThe bug was still evident, especially when using network throttling to\r\nadd slight lag to the request turnaround times.\r\n\r\nThis PR adds more handling of errors that could be thrown slightly prior\r\nto deleting the report document, when we try to clear all chunks of the\r\nreport using the content stream.\r\n\r\n<details>\r\n<summary>Before</summary>\r\n\r\n\r\n\r\n4c1f5edd
-73f1-4ca4-a40a-f900ca5f9c78\r\n\r\n\r\n</details>\r\n\r\n### Checklist\r\n- [x] Unit tests","sha":"dc813c351fe111c895e85a188372ad31625d8c8c","branchLabelMapping":{"^v8.13.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","backport:prev-minor","backport:prev-MAJOR","v8.12.0","v8.13.0","v8.11.4"],"number":173792,"url":"https://github.com/elastic/kibana/pull/173792","mergeCommit":{"message":"Handle content stream errors in report pre-deletion (#173792)\n\nRe-addresses https://github.com/elastic/kibana/issues/171363\r\n\r\nThe bug was still evident, especially when using network throttling to\r\nadd slight lag to the request turnaround times.\r\n\r\nThis PR adds more handling of errors that could be thrown slightly prior\r\nto deleting the report document, when we try to clear all chunks of the\r\nreport using the content stream.\r\n\r\n<details>\r\n<summary>Before</summary>\r\n\r\n\r\n\r\n4c1f5edd
-73f1-4ca4-a40a-f900ca5f9c78\r\n\r\n\r\n</details>\r\n\r\n### Checklist\r\n- [x] Unit tests","sha":"dc813c351fe111c895e85a188372ad31625d8c8c"}},"sourceBranch":"main","suggestedTargetBranches":["8.12","8.11"],"targetPullRequestStates":[{"branch":"8.12","label":"v8.12.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.13.0","labelRegex":"^v8.13.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/173792","number":173792,"mergeCommit":{"message":"Handle content stream errors in report pre-deletion (#173792)\n\nRe-addresses https://github.com/elastic/kibana/issues/171363\r\n\r\nThe bug was still evident, especially when using network throttling to\r\nadd slight lag to the request turnaround times.\r\n\r\nThis PR adds more handling of errors that could be thrown slightly prior\r\nto deleting the report document, when we try to clear all chunks of the\r\nreport using the content stream.\r\n\r\n<details>\r\n<summary>Before</summary>\r\n\r\n\r\n\r\n4c1f5edd
-73f1-4ca4-a40a-f900ca5f9c78\r\n\r\n\r\n</details>\r\n\r\n### Checklist\r\n- [x] Unit tests","sha":"dc813c351fe111c895e85a188372ad31625d8c8c"}},{"branch":"8.11","label":"v8.11.4","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
07dc7a1a9f
commit
eb687c43d6
3 changed files with 66 additions and 8 deletions
|
@ -99,7 +99,7 @@ describe('deleteJobResponseHandler', () => {
|
|||
ReturnType<typeof jobsQuery.get>
|
||||
>);
|
||||
jobsQuery.delete.mockRejectedValueOnce(
|
||||
Object.assign(new Error('Some error.'), { statusCode: 123 })
|
||||
Object.assign(new Error('Some error.'), { statusCode: 500 })
|
||||
);
|
||||
await deleteJobResponseHandler(
|
||||
core,
|
||||
|
@ -110,8 +110,7 @@ describe('deleteJobResponseHandler', () => {
|
|||
);
|
||||
|
||||
expect(response.customError).toHaveBeenCalledWith({
|
||||
statusCode: 123,
|
||||
body: 'Some error.',
|
||||
statusCode: 500,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { promisify } from 'util';
|
||||
import { kibanaResponseFactory } from 'kibana/server';
|
||||
import { ReportingCore } from '../../';
|
||||
import { ALLOWED_JOB_CONTENT_TYPES } from '../../../common/constants';
|
||||
|
@ -90,18 +89,41 @@ export async function deleteJobResponseHandler(
|
|||
|
||||
const docIndex = doc.index;
|
||||
const stream = await getContentStream(reporting, { id: docId, index: docIndex });
|
||||
const reportingSetup = reporting.getPluginSetupDeps();
|
||||
const logger = reportingSetup.logger.clone(['delete-report']);
|
||||
|
||||
// An "error" event is emitted if an error is
|
||||
// passed to the `stream.end` callback from
|
||||
// the _final method of the ContentStream.
|
||||
// This event must be handled.
|
||||
stream.on('error', (err) => {
|
||||
logger.error(err);
|
||||
});
|
||||
|
||||
try {
|
||||
/** @note Overwriting existing content with an empty buffer to remove all the chunks. */
|
||||
await promisify(stream.end.bind(stream, '', 'utf8'))();
|
||||
// Overwriting existing content with an
|
||||
// empty buffer to remove all the chunks.
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
stream.end('', 'utf8', (error?: Error) => {
|
||||
if (error) {
|
||||
// handle error that could be thrown
|
||||
// from the _write method of the ContentStream
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await jobsQuery.delete(docIndex, docId);
|
||||
|
||||
return res.ok({
|
||||
body: { deleted: true },
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return res.customError({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
statusCode: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,4 +363,41 @@ describe('GET /api/reporting/jobs/download', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete report', () => {
|
||||
const getCompleteHits = ({
|
||||
jobType = 'unencodedJobType',
|
||||
outputContentType = 'text/plain',
|
||||
title = '',
|
||||
} = {}) => {
|
||||
return getHits({
|
||||
jobtype: jobType,
|
||||
status: 'completed',
|
||||
output: { content_type: outputContentType },
|
||||
payload: { title },
|
||||
});
|
||||
};
|
||||
|
||||
it('handles content stream errors', async () => {
|
||||
stream = new Readable({
|
||||
read() {
|
||||
this.push('test');
|
||||
this.push(null);
|
||||
},
|
||||
}) as typeof stream;
|
||||
stream.end = jest.fn().mockImplementation((_name, _encoding, callback) => {
|
||||
callback(new Error('An error occurred in ending the content stream'));
|
||||
});
|
||||
|
||||
(getContentStream as jest.MockedFunction<typeof getContentStream>).mockResolvedValue(stream);
|
||||
mockEsClient.search.mockResolvedValueOnce({ body: getCompleteHits() } as any);
|
||||
registerJobInfoRoutes(core);
|
||||
|
||||
await server.start();
|
||||
await supertest(httpSetup.server.listener)
|
||||
.delete('/api/reporting/jobs/delete/denk')
|
||||
.expect(500)
|
||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue