use standardized error handling behavior

This commit is contained in:
spalger 2019-09-17 07:08:33 -07:00
parent 8dfcb733c6
commit 7e9a7f8dc5
4 changed files with 78 additions and 40 deletions

View file

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Axios, { AxiosRequestConfig } from 'axios';
export class Loader {
private readonly x = Axios.create({
...this.options,
headers: {
'kbn-xsrf': 'KibanaServerSavedObjects',
},
});
constructor(private readonly options: AxiosRequestConfig) {}
public async req<T>(desc: string, options: AxiosRequestConfig) {
try {
const resp = await this.x.request<T>(options);
return resp.data;
} catch (error) {
if (error.response) {
throw new Error(`Failed to ${desc}:\n${JSON.stringify(error.response.data, null, 2)}`);
}
throw error;
}
}
}

View file

@ -19,9 +19,10 @@
import Url from 'url';
import Axios, { AxiosRequestConfig } from 'axios';
import { ToolingLog } from '@kbn/dev-utils';
import { Loader } from './loader';
const joinPath = (...components: Array<string | undefined>) =>
`/${components
.filter((s): s is string => !!s)
@ -65,11 +66,8 @@ interface UpdateOptions<Attributes> extends IndexOptions<Attributes> {
}
export class KibanaServerSavedObjects {
private readonly x = Axios.create({
private readonly loader = new Loader({
baseURL: Url.resolve(this.url, '/api/saved_objects/'),
headers: {
'kbn-xsrf': 'KibanaServerSavedObjects',
},
});
constructor(private readonly url: string, private readonly log: ToolingLog) {}
@ -80,7 +78,7 @@ export class KibanaServerSavedObjects {
public async get<Attributes extends Record<string, any>>(options: GetOptions) {
this.log.debug('Gettings saved object: %j', options);
return await this.request<SavedObjectResponse<Attributes>>('get saved object', {
return await this.loader.req<SavedObjectResponse<Attributes>>('get saved object', {
url: joinPath(options.type, options.id),
method: 'GET',
});
@ -92,7 +90,7 @@ export class KibanaServerSavedObjects {
public async create<Attributes extends Record<string, any>>(options: IndexOptions<Attributes>) {
this.log.debug('Creating saved object: %j', options);
return await this.request<SavedObjectResponse<Attributes>>('update saved object', {
return await this.loader.req<SavedObjectResponse<Attributes>>('update saved object', {
url: joinPath(options.type, options.id),
params: {
overwrite: options.overwrite,
@ -112,7 +110,7 @@ export class KibanaServerSavedObjects {
public async update<Attributes extends Record<string, any>>(options: UpdateOptions<Attributes>) {
this.log.debug('Updating saved object: %j', options);
return await this.request<SavedObjectResponse<Attributes>>('update saved object', {
return await this.loader.req<SavedObjectResponse<Attributes>>('update saved object', {
url: joinPath(options.type, options.id),
params: {
overwrite: options.overwrite,
@ -132,22 +130,9 @@ export class KibanaServerSavedObjects {
public async delete(options: GetOptions) {
this.log.debug('Deleting saved object %s/%s', options);
return await this.request('delete saved object', {
return await this.loader.req('delete saved object', {
url: joinPath(options.type, options.id),
method: 'DELETE',
});
}
private async request<T>(desc: string, options: AxiosRequestConfig) {
try {
const resp = await this.x.request<T>(options);
return resp.data;
} catch (error) {
if (error.response) {
throw new Error(`Failed to ${desc}:\n${JSON.stringify(error.response.data, null, 2)}`);
}
throw error;
}
}
}

View file

@ -17,7 +17,7 @@
* under the License.
*/
import Axios from 'axios';
import { Loader } from './loader';
interface Status {
id: string;
@ -45,15 +45,16 @@ interface StatusResponse {
}
export class KibanaServerStatus {
private readonly x = Axios.create({
private readonly loader = new Loader({
baseURL: this.kibanaServerUrl,
});
constructor(private readonly kibanaServerUrl: string) {}
async get() {
const resp = await this.x.get<StatusResponse>('api/status');
return resp.data;
return await this.loader.req<StatusResponse>('get status', {
url: 'api/status',
});
}
async getOverallState() {

View file

@ -17,15 +17,17 @@
* under the License.
*/
import Axios from 'axios';
import Url from 'url';
import { get } from 'lodash';
import { Lifecycle } from '@kbn/test/types/ftr';
import { ToolingLog } from '@kbn/dev-utils';
import { Loader } from './loader';
export class KibanaServerUiSettings {
private readonly x = Axios.create({
baseURL: this.url,
private readonly loader = new Loader({
baseURL: Url.resolve(this.url, '/api/kibana/settings/'),
});
constructor(
@ -45,27 +47,31 @@ export class KibanaServerUiSettings {
* Gets defaultIndex from the config doc.
*/
async getDefaultIndex() {
const { data } = await this.x.get('/api/kibana/settings');
const data = await this.loader.req('get default index', {});
const defaultIndex = get(data, 'settings.defaultIndex.userValue');
this.log.verbose('uiSettings.defaultIndex: %j', defaultIndex);
return defaultIndex;
}
async replace(doc: Record<string, any>) {
const { data } = await this.x.get('/api/kibana/settings');
const data = await this.loader.req<Record<string, any>>('replace ui settings', {});
for (const key of Object.keys(data.settings)) {
if (!data.settings[key].isOverridden) {
await this.x.delete(`/api/kibana/settings/${key}`);
await this.loader.req(`delete ${key}`, {
url: key,
method: 'DELETE',
});
}
}
this.log.debug('replacing kibana config doc: %j', doc);
await this.x.post('/api/kibana/settings', {
changes: {
...this.defaults,
...doc,
await this.loader.req('replace kibana config doc', {
data: {
changes: {
...this.defaults,
...doc,
},
},
});
}
@ -75,8 +81,10 @@ export class KibanaServerUiSettings {
*/
async update(updates: Record<string, any>) {
this.log.debug('applying update to kibana config: %j', updates);
await this.x.post('/api/kibana/settings', {
changes: updates,
await this.loader.req('apply update to kibana config', {
data: {
changes: updates,
},
});
}
}