fix: Fix for 5xx error & errorWithDetail params
1. fix for 5xx error 2. change the order of errorWithDetail params Change-Id: I7a6807aeb5ca6d6c508d8bdf8dfdbd7e507705d9
This commit is contained in:
parent
6e86749e94
commit
15128f67e3
@ -256,7 +256,7 @@ export default class BaseForm extends React.Component {
|
||||
(err) => {
|
||||
this.updateSumbitting(false);
|
||||
this.responseError = err;
|
||||
this.showNotice && Notify.errorWithDetail(this.errorText, err);
|
||||
this.showNotice && Notify.errorWithDetail(err, this.errorText);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(err);
|
||||
if (callback && isFunction(callback)) {
|
||||
|
@ -25,6 +25,8 @@ import CodeEditor from 'components/CodeEditor';
|
||||
import ModalButton from 'components/ModalButton';
|
||||
import globalRootStore from 'stores/root';
|
||||
import { unescapeHtml } from 'utils/index';
|
||||
import { statusMap } from '@/resources/code';
|
||||
import { isEmpty, isString } from 'lodash';
|
||||
import styles from './index.less';
|
||||
|
||||
const open = (args) => {
|
||||
@ -122,29 +124,44 @@ const process = (title, description) => {
|
||||
});
|
||||
};
|
||||
|
||||
const errorWithDetail = (title, err) => {
|
||||
const description = err ? (
|
||||
<ModalButton
|
||||
style={{
|
||||
float: 'right',
|
||||
}}
|
||||
buttonType="link"
|
||||
buttonText={t('Click to show detail')}
|
||||
component={
|
||||
<CodeEditor
|
||||
className={styles.codeEditor}
|
||||
value={err}
|
||||
mode="json"
|
||||
options={{
|
||||
readOnly: true,
|
||||
}}
|
||||
/>
|
||||
const errorWithDetail = (err, title) => {
|
||||
const { status, message } = err || {};
|
||||
let nTitle = title;
|
||||
let description;
|
||||
if (status && parseInt(status, 10) >= 500) {
|
||||
if (!isEmpty(message) && !statusMap[status]) {
|
||||
if (isString(message)) {
|
||||
nTitle += `${t('message')}${t('.')}`;
|
||||
} else if (message.reason) {
|
||||
nTitle += `${t('message.reason')}${t('.')}`;
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
error(title, description);
|
||||
nTitle += `${t('Status Code')}: ${status}`;
|
||||
} else {
|
||||
nTitle += statusMap[status];
|
||||
}
|
||||
} else {
|
||||
// prettier-ignore
|
||||
description = err
|
||||
? <ModalButton
|
||||
style={{
|
||||
float: 'right',
|
||||
}}
|
||||
buttonType="link"
|
||||
buttonText={t('Click to show detail')}
|
||||
component={
|
||||
<CodeEditor
|
||||
className={styles.codeEditor}
|
||||
value={err}
|
||||
mode="json"
|
||||
options={{
|
||||
readOnly: true,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
: ''
|
||||
}
|
||||
error(nTitle, description);
|
||||
};
|
||||
|
||||
const Notify = {
|
||||
|
@ -220,7 +220,7 @@ export default class BaseStepForm extends React.Component {
|
||||
(err) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('reject', err);
|
||||
Notify.errorWithDetail(this.errorText, err);
|
||||
Notify.errorWithDetail(err, this.errorText);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -243,7 +243,7 @@ class ActionButton extends Component {
|
||||
const message = submitErrorMsgBatch
|
||||
? submitErrorMsgBatch(data)
|
||||
: getDefaultMsg(this.props.action, data).submitErrorMsgBatch;
|
||||
Notify.errorWithDetail(message, error);
|
||||
Notify.errorWithDetail(error, message);
|
||||
this.onCallback(false, true);
|
||||
};
|
||||
|
||||
@ -263,7 +263,7 @@ class ActionButton extends Component {
|
||||
const message = submitErrorMsg
|
||||
? submitErrorMsg(data, error)
|
||||
: getDefaultMsg(this.props.action, data).submitErrorMsg;
|
||||
Notify.errorWithDetail(message, error);
|
||||
Notify.errorWithDetail(error, message);
|
||||
this.onCallback(false, true);
|
||||
};
|
||||
|
||||
|
@ -491,10 +491,11 @@ export default class BaseList extends React.Component {
|
||||
message: t("You don't have access to get {name}.", {
|
||||
name: this.name.toLowerCase(),
|
||||
}),
|
||||
status: 401,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
t('Unable to get {name}.', { name: this.name.toLowerCase() }),
|
||||
error
|
||||
error,
|
||||
t('Unable to get {name}.', { name: this.name.toLowerCase() })
|
||||
);
|
||||
this.list.isLoading = false;
|
||||
this.list.silent = false;
|
||||
@ -515,14 +516,15 @@ export default class BaseList extends React.Component {
|
||||
const title = `${t('Get {name} error.', {
|
||||
name: this.name.toLowerCase(),
|
||||
})} ${sysErr}`;
|
||||
Notify.errorWithDetail(title);
|
||||
Notify.errorWithDetail(null, title);
|
||||
} else {
|
||||
const error = {
|
||||
message: data || message || e || '',
|
||||
status: e.status,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
t('Get {name} error.', { name: this.name.toLowerCase() }),
|
||||
error
|
||||
error,
|
||||
t('Get {name} error.', { name: this.name.toLowerCase() })
|
||||
);
|
||||
}
|
||||
this.list.isLoading = false;
|
||||
|
@ -223,10 +223,11 @@ export default class DetailBase extends React.Component {
|
||||
message: t("You don't have access to get {name}.", {
|
||||
name: this.name.toLowerCase(),
|
||||
}),
|
||||
status: 401,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
t('Unable to get {name} detail.', { name: this.name.toLowerCase() }),
|
||||
error
|
||||
error,
|
||||
t('Unable to get {name} detail.', { name: this.name.toLowerCase() })
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -260,10 +261,11 @@ export default class DetailBase extends React.Component {
|
||||
} else {
|
||||
const error = {
|
||||
message: e,
|
||||
status: e.code || e.status,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
t('Get {name} detail error.', { name: this.name.toLowerCase() }),
|
||||
error
|
||||
error,
|
||||
t('Get {name} detail error.', { name: this.name.toLowerCase() })
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
" You can go to the console to ": " You can go to the console to ",
|
||||
"\"Shared\" volume can be mounted on multiple instances": "\"Shared\" volume can be mounted on multiple instances",
|
||||
"-1 means no connection limit": "-1 means no connection limit",
|
||||
".": ".",
|
||||
"1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.": "1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.",
|
||||
"1. The name of the custom resource class property should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_BAREMETAL_SMALL).": "1. The name of the custom resource class property should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_BAREMETAL_SMALL).",
|
||||
"1. The name of the trait should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_TRAIT1).": "1. The name of the trait should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_TRAIT1).",
|
||||
@ -154,6 +155,7 @@
|
||||
"Backup Name": "Backup Name",
|
||||
"Backups": "Backups",
|
||||
"Backups & Snapshots": "Backups & Snapshots",
|
||||
"Bad Gateway (code: 502) ": "Bad Gateway (code: 502) ",
|
||||
"BandWidth Limit Egress": "BandWidth Limit Egress",
|
||||
"BandWidth Limit Ingress": "BandWidth Limit Ingress",
|
||||
"Bandwidth limit": "Bandwidth limit",
|
||||
@ -657,6 +659,7 @@
|
||||
"GPU pass-through will load GPU devices directly to the instance for use. VGPU is a GPU virtualization solution. GPU resources will be segmented and distributed to multiple instances for shared use.": "GPU pass-through will load GPU devices directly to the instance for use. VGPU is a GPU virtualization solution. GPU resources will be segmented and distributed to multiple instances for shared use.",
|
||||
"GRE": "GRE",
|
||||
"Gateway IP": "Gateway IP",
|
||||
"Gateway Time-out (code: 504) ": "Gateway Time-out (code: 504) ",
|
||||
"General Computing Type": "General Computing Type",
|
||||
"General Purpose": "General Purpose",
|
||||
"Get OpenRC file": "Get OpenRC file",
|
||||
@ -666,6 +669,7 @@
|
||||
"Gigabytes(GB)": "Gigabytes(GB)",
|
||||
"Given IP": "Given IP",
|
||||
"Global Setting": "Global Setting",
|
||||
"HTTP Version not supported (code: 505) ": "HTTP Version not supported (code: 505) ",
|
||||
"Hard Reboot": "Hard Reboot",
|
||||
"Hard Rebooting": "Hard Rebooting",
|
||||
"Health Monitor Delay": "Health Monitor Delay",
|
||||
@ -812,6 +816,7 @@
|
||||
"Internal Ip Address": "Internal Ip Address",
|
||||
"Internal Network Bandwidth(Gbps)": "Internal Network Bandwidth(Gbps)",
|
||||
"Internal Port": "Internal Port",
|
||||
"Internal Server Error (code: 500) ": "Internal Server Error (code: 500) ",
|
||||
"Invalid": "Invalid",
|
||||
"Invalid CIDR.": "Invalid CIDR.",
|
||||
"Invalid IP Address": "Invalid IP Address",
|
||||
@ -1011,6 +1016,7 @@
|
||||
"Node Name": "Node Name",
|
||||
"Node Num": "Node Num",
|
||||
"Normal": "Normal",
|
||||
"Not Implemented (code: 501) ": "Not Implemented (code: 501) ",
|
||||
"Not Open": "Not Open",
|
||||
"Not deleted with the instance": "Not deleted with the instance",
|
||||
"Not select": "Not select",
|
||||
@ -1362,6 +1368,7 @@
|
||||
"Service": "Service",
|
||||
"Service State": "Service State",
|
||||
"Service Status": "Service Status",
|
||||
"Service Unavailable (code: 503) ": "Service Unavailable (code: 503) ",
|
||||
"Services": "Services",
|
||||
"Set Boot Device": "Set Boot Device",
|
||||
"Set IP": "Set IP",
|
||||
@ -1431,6 +1438,7 @@
|
||||
"State": "State",
|
||||
"Static Routes": "Static Routes",
|
||||
"Status": "Status",
|
||||
"Status Code": "Status Code",
|
||||
"Stop": "Stop",
|
||||
"Stop Instance": "Stop Instance",
|
||||
"Stop auto refreshing data": "Stop auto refreshing data",
|
||||
@ -1855,6 +1863,8 @@
|
||||
"lock instance": "lock instance",
|
||||
"manage qos spec": "manage qos spec",
|
||||
"manage resource types": "manage resource types",
|
||||
"message": "message",
|
||||
"message.reason": "message.reason",
|
||||
"metadata": "metadata",
|
||||
"metadatas": "metadatas",
|
||||
"migrate": "migrate",
|
||||
|
@ -2,6 +2,7 @@
|
||||
" You can go to the console to ": "您可以前往控制台 ",
|
||||
"\"Shared\" volume can be mounted on multiple instances": "“共享”云硬盘类型的云硬盘,可挂载到多台云主机上",
|
||||
"-1 means no connection limit": "-1表示无连接限制",
|
||||
".": "。",
|
||||
"1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.": "1. 备份只能捕获在备份任务开始时已经写入磁盘的数据,不包括当时位于缓存的数据。",
|
||||
"1. The name of the custom resource class property should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_BAREMETAL_SMALL).": "1. 自定义资源属性的命名应该以 CUSTOM_ 开头、只能包含大写字母A ~ Z、数字0 ~ 9或下划线、长度不超过255个字符(比如:CUSTOM_BAREMETAL_SMALL)。",
|
||||
"1. The name of the trait should start with CUSTOM_, can only contain uppercase letters A ~ Z, numbers 0 ~ 9 or underscores, and the length should not exceed 255 characters (for example: CUSTOM_TRAIT1).": "1. 特性的命名应该以 CUSTOM_ 开头、只能包含大写字母A ~ Z、数字0 ~ 9或下划线、长度不超过255个字符(比如:CUSTOM_TRAIT1)。",
|
||||
@ -154,6 +155,7 @@
|
||||
"Backup Name": "备份名称",
|
||||
"Backups": "备份",
|
||||
"Backups & Snapshots": "备份和快照",
|
||||
"Bad Gateway (code: 502) ": "无效网关(错误码:502)",
|
||||
"BandWidth Limit Egress": "出方向带宽限制",
|
||||
"BandWidth Limit Ingress": "入方向带宽限制",
|
||||
"Bandwidth limit": "带宽限制",
|
||||
@ -657,6 +659,7 @@
|
||||
"GPU pass-through will load GPU devices directly to the instance for use. VGPU is a GPU virtualization solution. GPU resources will be segmented and distributed to multiple instances for shared use.": "GPU直通将GPU设备直接加载给云主机进行使用。vGPU是GPU虚拟化方案,GPU资源将被切分后分配给多个云主机共享使用。",
|
||||
"GRE": "",
|
||||
"Gateway IP": "网关IP",
|
||||
"Gateway Time-out (code: 504) ": "网关超时(错误码:504 )",
|
||||
"General Computing Type": "通用计算型",
|
||||
"General Purpose": "通用型",
|
||||
"Get OpenRC file": "获取Openstack RC 文件",
|
||||
@ -666,6 +669,7 @@
|
||||
"Gigabytes(GB)": "云硬盘容量(GB)",
|
||||
"Given IP": "指定IP",
|
||||
"Global Setting": "平台配置",
|
||||
"HTTP Version not supported (code: 505) ": "",
|
||||
"Hard Reboot": "硬重启",
|
||||
"Hard Rebooting": "硬重启中",
|
||||
"Health Monitor Delay": "检查间隔(秒)",
|
||||
@ -812,6 +816,7 @@
|
||||
"Internal Ip Address": "目标IP",
|
||||
"Internal Network Bandwidth(Gbps)": "内网带宽(Gbps)",
|
||||
"Internal Port": "目标端口",
|
||||
"Internal Server Error (code: 500) ": "服务器错误(错误码:500)",
|
||||
"Invalid": "失效",
|
||||
"Invalid CIDR.": "无效的CIDR",
|
||||
"Invalid IP Address": "无效的IP地址",
|
||||
@ -1011,6 +1016,7 @@
|
||||
"Node Name": "节点名称",
|
||||
"Node Num": "节点总数",
|
||||
"Normal": "正常",
|
||||
"Not Implemented (code: 501) ": "服务器不支持请求(错误码:501)",
|
||||
"Not Open": "未开放",
|
||||
"Not deleted with the instance": "不随云主机删除",
|
||||
"Not select": "不选择",
|
||||
@ -1362,6 +1368,7 @@
|
||||
"Service": "服务",
|
||||
"Service State": "服务状态",
|
||||
"Service Status": "管理状态",
|
||||
"Service Unavailable (code: 503) ": "服务不可用(错误码:503 )",
|
||||
"Services": "服务",
|
||||
"Set Boot Device": "设置引导设备",
|
||||
"Set IP": "设置IP",
|
||||
@ -1431,6 +1438,7 @@
|
||||
"State": "状态",
|
||||
"Static Routes": "静态路由",
|
||||
"Status": "状态",
|
||||
"Status Code": "",
|
||||
"Stop": "关闭",
|
||||
"Stop Instance": "关闭云主机",
|
||||
"Stop auto refreshing data": "关闭自动刷新数据",
|
||||
@ -1855,6 +1863,8 @@
|
||||
"lock instance": "锁定云主机",
|
||||
"manage qos spec": "管理QoS规格",
|
||||
"manage resource types": "管理资源类型",
|
||||
"message": "",
|
||||
"message.reason": "",
|
||||
"metadata": "元数据",
|
||||
"metadatas": "元数据",
|
||||
"migrate": "迁移",
|
||||
|
@ -370,7 +370,7 @@ class StepCreate extends StepAction {
|
||||
) {
|
||||
Notify.error(t('Quota exceeded'));
|
||||
} else {
|
||||
Notify.errorWithDetail(this.errorText, err);
|
||||
Notify.errorWithDetail(err, this.errorText);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -144,14 +144,14 @@ export default class CreateNetwork extends ModalAction {
|
||||
(err) => {
|
||||
const { type, error } = JSON.parse(err);
|
||||
if (type === 'create_network') {
|
||||
Notify.errorWithDetail(this.errorText, error);
|
||||
Notify.errorWithDetail(error, this.errorText);
|
||||
} else if (type === 'create_subnet') {
|
||||
Notify.errorWithDetail(
|
||||
error,
|
||||
t('Unable to {action}, instance: {name}.', {
|
||||
action: t('Create Subnet'),
|
||||
name: values.subnet_name,
|
||||
}),
|
||||
error
|
||||
})
|
||||
);
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
|
8
src/resources/code.js
Normal file
8
src/resources/code.js
Normal file
@ -0,0 +1,8 @@
|
||||
export const statusMap = {
|
||||
500: t('Internal Server Error (code: 500) '),
|
||||
501: t('Not Implemented (code: 501) '),
|
||||
502: t('Bad Gateway (code: 502) '),
|
||||
503: t('Service Unavailable (code: 503) '),
|
||||
504: t('Gateway Time-out (code: 504) '),
|
||||
505: t('HTTP Version not supported (code: 505) '),
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user