Web console: Better manual capabilities detection indication (#16191)

* Better forced mode indication

* more robust

* Update web-console/src/components/header-bar/header-bar.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/header-bar.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/__snapshots__/restricted-mode.spec.tsx.snap

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/__snapshots__/restricted-mode.spec.tsx.snap

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* Update web-console/src/components/header-bar/restricted-mode/restricted-mode.tsx

Co-authored-by: Charles Smith <techdocsmith@gmail.com>

* reformat

* forced => manual capability detection

* typo

* typo2

---------

Co-authored-by: Charles Smith <techdocsmith@gmail.com>
This commit is contained in:
Vadim Ogievetsky 2024-04-08 10:07:21 -07:00 committed by GitHub
parent f4649fece9
commit 4ff7e2c6c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 509 additions and 225 deletions

View File

@ -267,55 +267,53 @@ exports[`HeaderBar matches snapshot 1`] = `
<Blueprint4.MenuItem
active={false}
disabled={false}
icon="cog"
icon="high-priority"
multiline={false}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Console options"
text="Capabilty detection"
>
<React.Fragment>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Force Coordinator/Overlord mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Force Coordinator mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Force Overlord mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Force no management proxy mode"
/>
</React.Fragment>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Manually set Coordinator/Overlord mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Manually set Coordinator mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Manually set Overlord mode"
/>
<Blueprint4.MenuItem
active={false}
disabled={false}
multiline={false}
onClick={[Function]}
popoverProps={{}}
selected={false}
shouldDismissPopover={true}
text="Manually set Router with no management proxy mode"
/>
</Blueprint4.MenuItem>
</Blueprint4.Menu>
}

View File

@ -32,7 +32,6 @@ import {
} from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { Popover2 } from '@blueprintjs/popover2';
import type { JSX } from 'react';
import React, { useState } from 'react';
import {
@ -51,9 +50,10 @@ import {
localStorageSetJson,
oneOf,
} from '../../utils';
import { ExternalLink } from '../external-link/external-link';
import { PopoverText } from '../popover-text/popover-text';
import { RestrictedMode } from './restricted-mode/restricted-mode';
import './header-bar.scss';
const capabilitiesOverride = localStorageGetJson(LocalStorageKeys.CAPABILITIES_OVERRIDE);
@ -92,143 +92,6 @@ const DruidLogo = React.memo(function DruidLogo() {
);
});
interface RestrictedModeProps {
capabilities: Capabilities;
onUnrestrict(capabilities: Capabilities): void;
}
const RestrictedMode = React.memo(function RestrictedMode(props: RestrictedModeProps) {
const { capabilities, onUnrestrict } = props;
const mode = capabilities.getModeExtended();
let label: string;
let message: JSX.Element;
switch (mode) {
case 'full':
return null; // Do not show anything
case 'no-sql':
label = 'No SQL mode';
message = (
<p>
It appears that the SQL endpoint is disabled. The console will fall back to{' '}
<ExternalLink href={getLink('DOCS_API')}>native Druid APIs</ExternalLink> and will be
limited in functionality. Look at{' '}
<ExternalLink href={getLink('DOCS_SQL')}>the SQL docs</ExternalLink> to enable the SQL
endpoint.
</p>
);
break;
case 'no-proxy':
label = 'No management proxy mode';
message = (
<p>
It appears that the management proxy is not enabled, the console will operate with limited
functionality.
</p>
);
break;
case 'no-sql-no-proxy':
label = 'No SQL mode';
message = (
<p>
It appears that the SQL endpoint and management proxy are disabled. The console can only
be used to make queries.
</p>
);
break;
case 'coordinator-overlord':
label = 'Coordinator/Overlord mode';
message = (
<p>
It appears that you are accessing the console on the Coordinator/Overlord shared service.
Due to the lack of access to some APIs on this service the console will operate in a
limited mode. The unrestricted version of the console can be accessed on the Router
service.
</p>
);
break;
case 'coordinator':
label = 'Coordinator mode';
message = (
<p>
It appears that you are accessing the console on the Coordinator service. Due to the lack
of access to some APIs on this service the console will operate in a limited mode. The
full version of the console can be accessed on the Router service.
</p>
);
break;
case 'overlord':
label = 'Overlord mode';
message = (
<p>
It appears that you are accessing the console on the Overlord service. Due to the lack of
access to some APIs on this service the console will operate in a limited mode. The
unrestricted version of the console can be accessed on the Router service.
</p>
);
break;
default:
label = 'Restricted mode';
message = (
<p>
Due to the lack of access to some APIs on this service the console will operate in a
limited mode. The unrestricted version of the console can be accessed on the Router
service.
</p>
);
break;
}
return (
<Popover2
content={
<PopoverText>
<p>The console is running in restricted mode.</p>
{message}
<p>
For more info check out the{' '}
<ExternalLink href={`${getLink('DOCS')}/operations/web-console.html`}>
web console documentation
</ExternalLink>
.
</p>
<p>
It is possible that there is an issue with the capability detection. You can enable the
unrestricted console but certain features might not work if the underlying APIs are not
available.
</p>
<p>
<Button
icon={IconNames.WARNING_SIGN}
text={`Temporarily unrestrict console${capabilities.hasSql() ? '' : ' (with SQL)'}`}
onClick={() => onUnrestrict(Capabilities.FULL)}
/>
</p>
{!capabilities.hasSql() && (
<p>
<Button
icon={IconNames.WARNING_SIGN}
text="Temporarily unrestrict console (without SQL)"
onClick={() => onUnrestrict(Capabilities.NO_SQL)}
/>
</p>
)}
</PopoverText>
}
position={Position.BOTTOM_RIGHT}
>
<Button icon={IconNames.WARNING_SIGN} text={label} intent={Intent.WARNING} minimal />
</Popover2>
);
});
export interface HeaderBarProps {
active: HeaderActiveTab;
capabilities: Capabilities;
@ -324,7 +187,7 @@ export const HeaderBar = React.memo(function HeaderBar(props: HeaderBarProps) {
</Menu>
);
function setForcedMode(capabilities: Capabilities | undefined): void {
function setCapabilitiesOverride(capabilities: Capabilities | undefined): void {
if (capabilities) {
localStorageSetJson(LocalStorageKeys.CAPABILITIES_OVERRIDE, capabilities);
} else {
@ -360,39 +223,46 @@ export const HeaderBar = React.memo(function HeaderBar(props: HeaderBarProps) {
onClick={() => setCompactionDynamicConfigDialogOpen(true)}
disabled={!capabilities.hasCoordinatorAccess()}
/>
<MenuDivider />
<MenuItem icon={IconNames.COG} text="Console options">
{capabilitiesOverride ? (
<MenuItem text="Clear forced mode" onClick={() => setForcedMode(undefined)} />
) : (
<MenuItem
icon={IconNames.HIGH_PRIORITY}
text="Capabilty detection"
intent={capabilitiesOverride ? Intent.DANGER : undefined}
>
{capabilitiesOverride && (
<>
{capabilitiesMode !== 'coordinator-overlord' && (
<MenuItem
text="Force Coordinator/Overlord mode"
onClick={() => setForcedMode(Capabilities.COORDINATOR_OVERLORD)}
/>
)}
{capabilitiesMode !== 'coordinator' && (
<MenuItem
text="Force Coordinator mode"
onClick={() => setForcedMode(Capabilities.COORDINATOR)}
/>
)}
{capabilitiesMode !== 'overlord' && (
<MenuItem
text="Force Overlord mode"
onClick={() => setForcedMode(Capabilities.OVERLORD)}
/>
)}
{capabilitiesMode !== 'no-proxy' && (
<MenuItem
text="Force no management proxy mode"
onClick={() => setForcedMode(Capabilities.NO_PROXY)}
/>
)}
<MenuItem
text="Use automatic capabilty detection"
onClick={() => setCapabilitiesOverride(undefined)}
intent={Intent.PRIMARY}
/>
<MenuDivider />
</>
)}
{capabilitiesMode !== 'coordinator-overlord' && (
<MenuItem
text="Manually set Coordinator/Overlord mode"
onClick={() => setCapabilitiesOverride(Capabilities.COORDINATOR_OVERLORD)}
/>
)}
{capabilitiesMode !== 'coordinator' && (
<MenuItem
text="Manually set Coordinator mode"
onClick={() => setCapabilitiesOverride(Capabilities.COORDINATOR)}
/>
)}
{capabilitiesMode !== 'overlord' && (
<MenuItem
text="Manually set Overlord mode"
onClick={() => setCapabilitiesOverride(Capabilities.OVERLORD)}
/>
)}
{capabilitiesMode !== 'no-proxy' && (
<MenuItem
text="Manually set Router with no management proxy mode"
onClick={() => setCapabilitiesOverride(Capabilities.NO_PROXY)}
/>
)}
</MenuItem>
</Menu>
);
@ -495,7 +365,48 @@ export const HeaderBar = React.memo(function HeaderBar(props: HeaderBarProps) {
</Popover2>
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
<RestrictedMode capabilities={capabilities} onUnrestrict={onUnrestrict} />
<RestrictedMode
capabilities={capabilities}
onUnrestrict={onUnrestrict}
onUseAutomaticCapabilityDetection={
capabilitiesOverride ? () => setCapabilitiesOverride(undefined) : undefined
}
/>
{capabilitiesOverride && (
<Popover2
content={
<PopoverText>
<p>
The console is running in a manual capability setting mode that assumes a limited
set of capabilities rather than detecting all capabilities for the cluster.
</p>
<p>
Manual capability setting mode is an advanced feature used for testing and for
working around issues with the automatic capability detecting logic.
</p>
<p>
If you are unsure why the console is in this mode, revert to using automatic
capability detection.
</p>
<p>
<Button
text="Use automatic capability detection"
onClick={() => setCapabilitiesOverride(undefined)}
intent={Intent.PRIMARY}
/>
</p>
</PopoverText>
}
position={Position.BOTTOM_RIGHT}
>
<Button
icon={IconNames.HIGH_PRIORITY}
text="Manual capabilty detection"
intent={Intent.DANGER}
minimal
/>
</Popover2>
)}
<Popover2 content={configMenu} position={Position.BOTTOM_RIGHT}>
<Button className="header-entry" minimal icon={IconNames.COG} />
</Popover2>

View File

@ -0,0 +1,143 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`RestrictedMode matches snapshot when in auto capability detection mode 1`] = `
<Blueprint4.Popover2
boundary="clippingParents"
captureDismiss={false}
className="restricted-mode"
content={
<Memo(PopoverText)>
<p>
The console is running in restricted mode.
</p>
<p>
You are accessing the console on the Coordinator/Overlord shared service. Because this service lacks access to some APIs, the console will operate in a limited mode. You can access the unrestricted version of the console on the Router service.
</p>
<p>
For more info refer to the
<Memo(ExternalLink)
href="https://druid.apache.org/docs/latest/operations/web-console.html"
>
web console documentation
</Memo(ExternalLink)>
.
</p>
<React.Fragment>
<p>
It is possible that the console is experiencing an issue with the capability detection. You can enable the unrestricted console, but certain features might not work if the underlying APIs are not available.
</p>
<p>
<Blueprint4.Button
icon="warning-sign"
onClick={[Function]}
text="Temporarily unrestrict console (with SQL)"
/>
</p>
</React.Fragment>
<p>
<Blueprint4.Button
icon="warning-sign"
onClick={[Function]}
text="Temporarily unrestrict console (without SQL)"
/>
</p>
</Memo(PopoverText)>
}
defaultIsOpen={false}
disabled={false}
fill={false}
hasBackdrop={false}
hoverCloseDelay={300}
hoverOpenDelay={150}
inheritDarkTheme={true}
interactionKind="click"
matchTargetWidth={false}
minimal={false}
openOnTargetFocus={true}
position="bottom-right"
positioningStrategy="absolute"
shouldReturnFocusOnClose={false}
targetTagName="span"
transitionDuration={300}
usePortal={true}
>
<Blueprint4.Button
icon="warning-sign"
intent="warning"
minimal={true}
text="Coordinator/Overlord mode"
/>
</Blueprint4.Popover2>
`;
exports[`RestrictedMode matches snapshot when in manual capability detection mode 1`] = `
<Blueprint4.Popover2
boundary="clippingParents"
captureDismiss={false}
className="restricted-mode"
content={
<Memo(PopoverText)>
<p>
The console is running in restricted mode.
</p>
<p>
You are accessing the console on the Coordinator/Overlord shared service. Because this service lacks access to some APIs, the console will operate in a limited mode. You can access the unrestricted version of the console on the Router service.
</p>
<p>
For more info refer to the
<Memo(ExternalLink)
href="https://druid.apache.org/docs/latest/operations/web-console.html"
>
web console documentation
</Memo(ExternalLink)>
.
</p>
<React.Fragment>
<p>
The console did no perform its automatic capability detection because it is running in manual capability detection mode.
</p>
<p>
<Blueprint4.Button
intent="primary"
onClick={[Function]}
text="Use to automatic capability detection"
/>
</p>
</React.Fragment>
<p>
<Blueprint4.Button
icon="warning-sign"
onClick={[Function]}
text="Temporarily unrestrict console (without SQL)"
/>
</p>
</Memo(PopoverText)>
}
defaultIsOpen={false}
disabled={false}
fill={false}
hasBackdrop={false}
hoverCloseDelay={300}
hoverOpenDelay={150}
inheritDarkTheme={true}
interactionKind="click"
matchTargetWidth={false}
minimal={false}
openOnTargetFocus={true}
position="bottom-right"
positioningStrategy="absolute"
shouldReturnFocusOnClose={false}
targetTagName="span"
transitionDuration={300}
usePortal={true}
>
<Blueprint4.Button
icon="warning-sign"
intent="warning"
minimal={true}
text="Coordinator/Overlord mode"
/>
</Blueprint4.Popover2>
`;

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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 React from 'react';
import { Capabilities } from '../../../helpers';
import { shallow } from '../../../utils/shallow-renderer';
import { RestrictedMode } from './restricted-mode';
describe('RestrictedMode', () => {
it('matches snapshot when in auto capability detection mode', () => {
const headerBar = shallow(
<RestrictedMode capabilities={Capabilities.COORDINATOR_OVERLORD} onUnrestrict={() => {}} />,
);
expect(headerBar).toMatchSnapshot();
});
it('matches snapshot when in manual capability detection mode', () => {
const headerBar = shallow(
<RestrictedMode
capabilities={Capabilities.COORDINATOR_OVERLORD}
onUnrestrict={() => {}}
onUseAutomaticCapabilityDetection={() => {}}
/>,
);
expect(headerBar).toMatchSnapshot();
});
});

View File

@ -0,0 +1,184 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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 { Button, Intent, Position } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { Popover2 } from '@blueprintjs/popover2';
import React, { type JSX } from 'react';
import { Capabilities } from '../../../helpers';
import { getLink } from '../../../links';
import { ExternalLink } from '../../external-link/external-link';
import { PopoverText } from '../../popover-text/popover-text';
export interface RestrictedModeProps {
capabilities: Capabilities;
onUnrestrict(capabilities: Capabilities): void;
onUseAutomaticCapabilityDetection?: () => void;
}
export const RestrictedMode = React.memo(function RestrictedMode(props: RestrictedModeProps) {
const { capabilities, onUnrestrict, onUseAutomaticCapabilityDetection } = props;
const mode = capabilities.getModeExtended();
let label: string;
let message: JSX.Element;
switch (mode) {
case 'full':
return null; // Do not show anything
case 'no-sql':
label = 'No SQL mode';
message = (
<p>
The SQL endpoint is disabled. The console will fall back to{' '}
<ExternalLink href={getLink('DOCS_API')}>native Druid APIs</ExternalLink> and will operate
with limited functionality. Refer to{' '}
<ExternalLink href={getLink('DOCS_SQL')}>the SQL docs</ExternalLink> for instructions to
enable the SQL endpoint.
</p>
);
break;
case 'no-proxy':
label = 'No management proxy mode';
message = (
<p>
The management proxy is disabled, the console will operate with limited functionality.
</p>
);
break;
case 'no-sql-no-proxy':
label = 'No SQL mode';
message = (
<p>
The SQL endpoint and management proxy are disabled. You can only use the console to make
JSON-based queries.
</p>
);
break;
case 'coordinator-overlord':
label = 'Coordinator/Overlord mode';
message = (
<p>
You are accessing the console on the Coordinator/Overlord shared service. Because this
service lacks access to some APIs, the console will operate in a limited mode. You can
access the unrestricted version of the console on the Router service.
</p>
);
break;
case 'coordinator':
label = 'Coordinator mode';
message = (
<p>
You are accessing the console on the Coordinator service. Because this service lacks
access to some APIs, the console will operate in a limited mode. You can access the
unrestricted version of the console on the Router service.
</p>
);
break;
case 'overlord':
label = 'Overlord mode';
message = (
<p>
You are accessing the console on the Overlord service. Because this service lacks access
to some APIs, the console will operate in a limited mode. You can access the unrestricted
version of the console on the Router service.
</p>
);
break;
default:
label = 'Restricted mode';
message = (
<p>
Due to the lack of access to some APIs on this service, the console will operate in a
limited mode. You can access the unrestricted version of the console on the Router
service.
</p>
);
break;
}
return (
<Popover2
className="restricted-mode"
content={
<PopoverText>
<p>The console is running in restricted mode.</p>
{message}
<p>
For more info refer to the{' '}
<ExternalLink href={`${getLink('DOCS')}/operations/web-console.html`}>
web console documentation
</ExternalLink>
.
</p>
{onUseAutomaticCapabilityDetection ? (
<>
<p>
The console did no perform its automatic capability detection because it is running
in manual capability detection mode.
</p>
<p>
<Button
text="Use to automatic capability detection"
onClick={onUseAutomaticCapabilityDetection}
intent={Intent.PRIMARY}
/>
</p>
</>
) : (
<>
<p>
It is possible that the console is experiencing an issue with the capability
detection. You can enable the unrestricted console, but certain features might not
work if the underlying APIs are not available.
</p>
<p>
<Button
icon={IconNames.WARNING_SIGN}
text={`Temporarily unrestrict console${
capabilities.hasSql() ? '' : ' (with SQL)'
}`}
onClick={() => onUnrestrict(Capabilities.FULL)}
/>
</p>
</>
)}
{!capabilities.hasSql() && (
<p>
<Button
icon={IconNames.WARNING_SIGN}
text="Temporarily unrestrict console (without SQL)"
onClick={() => onUnrestrict(Capabilities.NO_SQL)}
/>
</p>
)}
</PopoverText>
}
position={Position.BOTTOM_RIGHT}
>
<Button icon={IconNames.WARNING_SIGN} text={label} intent={Intent.WARNING} minimal />
</Popover2>
);
});

View File

@ -122,7 +122,8 @@ export class ConsoleApplication extends React.PureComponent<
return await Capabilities.detectCapacity(capabilities);
},
onStateChange: ({ data, loading }) => {
onStateChange: ({ data, loading, error }) => {
console.error('There was an error retrieving the capabilities', error);
this.setState({
capabilities: data || Capabilities.FULL,
capabilitiesLoading: loading,

View File

@ -65,8 +65,8 @@ export class Capabilities {
{ timeout: Capabilities.STATUS_TIMEOUT },
);
} catch (e) {
const { response } = e;
if (response.status !== 405 && response.status !== 404) {
const status = e.response?.status;
if (status !== 405 && status !== 404) {
return; // other failure
}
try {
@ -87,7 +87,7 @@ export class Capabilities {
{ timeout: Capabilities.STATUS_TIMEOUT },
);
} catch (e) {
if (response.status !== 405 && response.status !== 404) {
if (status !== 405 && status !== 404) {
return; // other failure
}
@ -106,9 +106,9 @@ export class Capabilities {
timeout: Capabilities.STATUS_TIMEOUT,
});
} catch (e) {
const { response } = e;
const status = e.response?.status;
// If we detect error code 400 the management proxy is enabled but just does not know about the recently added /proxy/enabled route so treat this as a win.
return response.status === 400;
return status === 400;
}
return true;

View File

@ -25,7 +25,6 @@ export async function getClusterCapacity(): Promise<CapacityInfo> {
});
const usedTaskSlots = Number(workersResponse.data.usedClusterCapacity);
const totalTaskSlots = Number(workersResponse.data.currentClusterCapacity);
return {

View File

@ -16,8 +16,8 @@
* limitations under the License.
*/
import type { AxiosError, AxiosInstance, CreateAxiosDefaults } from 'axios';
import axios from 'axios';
import type { AxiosInstance, CreateAxiosDefaults } from 'axios';
import axios, { AxiosError } from 'axios';
import * as JSONBig from 'json-bigint-native';
import { nonEmptyString } from '../utils';
@ -36,11 +36,15 @@ export class Api {
const responseData = error.response?.data;
const message = responseData?.message;
if (nonEmptyString(message)) {
return Promise.reject(new Error(message));
return Promise.reject(
new AxiosError(message, error.code, error.config, error.request, error.response),
);
}
if (error.config?.method?.toLowerCase() === 'get' && nonEmptyString(responseData)) {
return Promise.reject(new Error(responseData));
return Promise.reject(
new AxiosError(responseData, error.code, error.config, error.request, error.response),
);
}
return Promise.reject(error);