mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Allow passing in a signal to abort a cluster client request (#37563)
* Allow passing in a signal to abort an Elasticsearch request using the cluster client * Go back to using promises (which still return abort method) and update test * Update docs * Explicitly return Promise<any> instead of {}
This commit is contained in:
parent
78a6c3dd4e
commit
6ca6b1ad92
6 changed files with 50 additions and 2 deletions
|
@ -16,5 +16,6 @@ export interface CallAPIOptions
|
|||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [signal](./kibana-plugin-server.callapioptions.signal.md) | <code>AbortSignal</code> | A signal object that allows you to abort the request via an AbortController object. |
|
||||
| [wrap401Errors](./kibana-plugin-server.callapioptions.wrap401errors.md) | <code>boolean</code> | Indicates whether <code>401 Unauthorized</code> errors returned from the Elasticsearch API should be wrapped into <code>Boom</code> error instances with properly set <code>WWW-Authenticate</code> header that could have been returned by the API itself. If API didn't specify that then <code>Basic realm="Authorization Required"</code> is used as <code>WWW-Authenticate</code>. |
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [CallAPIOptions](./kibana-plugin-server.callapioptions.md) > [signal](./kibana-plugin-server.callapioptions.signal.md)
|
||||
|
||||
## CallAPIOptions.signal property
|
||||
|
||||
A signal object that allows you to abort the request via an AbortController object.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
signal?: AbortSignal;
|
||||
```
|
|
@ -165,6 +165,25 @@ describe('#callAsInternalUser', () => {
|
|||
).rejects.toStrictEqual(mockAuthenticationError);
|
||||
});
|
||||
|
||||
test('aborts the request and rejects if a signal is provided and aborted', async () => {
|
||||
const controller = new AbortController();
|
||||
|
||||
// The ES client returns a promise with an additional `abort` method to abort the request
|
||||
const mockValue: any = Promise.resolve();
|
||||
mockValue.abort = jest.fn();
|
||||
mockEsClientInstance.ping.mockReturnValue(mockValue);
|
||||
|
||||
const promise = clusterClient.callAsInternalUser('ping', undefined, {
|
||||
wrap401Errors: false,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
controller.abort();
|
||||
|
||||
expect(mockValue.abort).toHaveBeenCalled();
|
||||
await expect(promise).rejects.toThrowErrorMatchingInlineSnapshot(`"Request was aborted"`);
|
||||
});
|
||||
|
||||
test('does not override WWW-Authenticate if returned by Elasticsearch', async () => {
|
||||
const mockAuthenticationError = new (errors.AuthenticationException as any)(
|
||||
'Authentication Exception',
|
||||
|
|
|
@ -42,6 +42,10 @@ export interface CallAPIOptions {
|
|||
* then `Basic realm="Authorization Required"` is used as `WWW-Authenticate`.
|
||||
*/
|
||||
wrap401Errors: boolean;
|
||||
/**
|
||||
* A signal object that allows you to abort the request via an AbortController object.
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +61,7 @@ async function callAPI(
|
|||
endpoint: string,
|
||||
clientParams: Record<string, unknown> = {},
|
||||
options: CallAPIOptions = { wrap401Errors: true }
|
||||
) {
|
||||
): Promise<any> {
|
||||
const clientPath = endpoint.split('.');
|
||||
const api: any = get(client, clientPath);
|
||||
if (!api) {
|
||||
|
@ -66,7 +70,16 @@ async function callAPI(
|
|||
|
||||
const apiContext = clientPath.length === 1 ? client : get(client, clientPath.slice(0, -1));
|
||||
try {
|
||||
return await api.call(apiContext, clientParams);
|
||||
return await new Promise((resolve, reject) => {
|
||||
const request = api.call(apiContext, clientParams);
|
||||
if (options.signal) {
|
||||
options.signal.addEventListener('abort', () => {
|
||||
request.abort();
|
||||
reject(new Error('Request was aborted'));
|
||||
});
|
||||
}
|
||||
return request.then(resolve, reject);
|
||||
});
|
||||
} catch (err) {
|
||||
if (!options.wrap401Errors || err.statusCode !== 401) {
|
||||
throw err;
|
||||
|
|
|
@ -43,6 +43,7 @@ export function bootstrap({ configs, cliArgs, applyConfigOverrides, features, }:
|
|||
|
||||
// @public
|
||||
export interface CallAPIOptions {
|
||||
signal?: AbortSignal;
|
||||
wrap401Errors: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ export interface DeprecationAPIResponse {
|
|||
|
||||
export interface CallClusterOptions {
|
||||
wrap401Errors?: boolean;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
export interface CallClusterWithRequest {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue