forked from CITKParus/P8-Panels
ЦИТК-929 - Вывод сообщения об ошибке без стэка вызова
This commit is contained in:
commit
9f99c99643
@ -1100,7 +1100,8 @@ const Mui = ({ title }) => {
|
||||
`type` - обязательный, строка, тип отображаемого сообщения, `information|warning|error` (см. константу `MSG_TYPE` в "app/context/messaging_reducer" и константу `P8P_APP_MESSAGE_VARIANT` в "app/components/p8p_app_message")\
|
||||
`text` - обязательный, строка, текст отображаемого сообщения\
|
||||
`msgOnOk` - необязательный, функция, будет вызвана при нажатии на "ОК"/"ЗАКРЫТЬ" в сообщении
|
||||
`msgOnCancel` - необязательный, функция, будет вызвана при нажатии на "ОТМЕНА" в сообщении (только для сообщений типа `warning`)
|
||||
`msgOnCancel` - необязательный, функция, будет вызвана при нажатии на "ОТМЕНА" в сообщении (только для сообщений типа `warning`)\
|
||||
`fullErrorText` - необязательный, строка, полный текст ошибки, используется только при `type="error"`. Если параметр указан, то в окно ошибки выводится кнопка "Подробнее", по нажатию на которую будет отображаться текст, указанный в данном параметре
|
||||
|
||||
**Результат:** функция не возвращает значимого результата
|
||||
|
||||
@ -1108,7 +1109,11 @@ const Mui = ({ title }) => {
|
||||
|
||||
Декоратор для `showMsg`, отображает модальное окно сообщения типа "Ошибка" (`type="error"`).
|
||||
|
||||
**Входные параметры:** аналогично `showMsg`
|
||||
**Входные параметры:**
|
||||
|
||||
`text` - обязательный, строка, текст отображаемого сообщения\
|
||||
`msgOnOk` - необязательный, функция, будет вызвана при нажатии на "ЗАКРЫТЬ" в сообщении
|
||||
`fullErrorText` - необязательный, строка, полный текст ошибки. Если параметр указан, то в окно ошибки выводится кнопка "Подробнее", по нажатию на которую будет отображаться текст, указанный в данном параметре
|
||||
|
||||
**Результат:** аналогично `showMsg`
|
||||
|
||||
|
@ -29,6 +29,8 @@ export const BUTTONS = {
|
||||
OK: "ОК", //Ок
|
||||
CANCEL: "Отмена", //Отмена
|
||||
CLOSE: "Закрыть", //Сокрытие
|
||||
DETAIL: "Подробнее", //Отображение подробного текста
|
||||
HIDE: "Скрыть", //Скрытие информации
|
||||
CLEAR: "Очистить", //Очистка
|
||||
ORDER_ASC: "По возрастанию", //Сортировка по возрастанию
|
||||
ORDER_DESC: "По убыванию", //Сортировка по убыванию
|
||||
|
@ -7,7 +7,7 @@
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import React, { useState } from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import Dialog from "@mui/material/Dialog"; //базовый класс диалога Material UI
|
||||
import DialogTitle from "@mui/material/DialogTitle"; //Заголовок диалога
|
||||
@ -66,7 +66,25 @@ const STYLES = {
|
||||
//-----------
|
||||
|
||||
//Сообщение
|
||||
const P8PAppMessage = ({ variant, title, titleText, cancelBtn, onCancel, cancelBtnCaption, okBtn, onOk, okBtnCaption, open, text }) => {
|
||||
const P8PAppMessage = ({
|
||||
variant,
|
||||
title,
|
||||
titleText,
|
||||
cancelBtn,
|
||||
onCancel,
|
||||
cancelBtnCaption,
|
||||
okBtn,
|
||||
onOk,
|
||||
okBtnCaption,
|
||||
open,
|
||||
text,
|
||||
fullErrorText,
|
||||
showErrMoreCaption,
|
||||
hideErrMoreCaption
|
||||
}) => {
|
||||
//Состояние подробной информации об ошибке
|
||||
const [showFullErrorText, setShowFullErrorText] = useState(false);
|
||||
|
||||
//Подбор стиля и ресурсов
|
||||
let style = STYLES.INFO;
|
||||
switch (variant) {
|
||||
@ -107,11 +125,21 @@ const P8PAppMessage = ({ variant, title, titleText, cancelBtn, onCancel, cancelB
|
||||
</Button>
|
||||
);
|
||||
|
||||
//Кнопка Подробнее
|
||||
let fullErrorTextBtn;
|
||||
if (fullErrorText && showErrMoreCaption && hideErrMoreCaption && variant === P8P_APP_MESSAGE_VARIANT.ERR)
|
||||
fullErrorTextBtn = (
|
||||
<Button onClick={() => setShowFullErrorText(!showFullErrorText)} color="warning" autoFocus>
|
||||
{!showFullErrorText ? showErrMoreCaption : hideErrMoreCaption}
|
||||
</Button>
|
||||
);
|
||||
|
||||
//Все действия
|
||||
let actionsPart;
|
||||
if (cancelBtnPart || okBtnPart)
|
||||
actionsPart = (
|
||||
<DialogActions>
|
||||
{fullErrorTextBtn}
|
||||
{okBtnPart}
|
||||
{cancelBtnPart}
|
||||
</DialogActions>
|
||||
@ -128,7 +156,7 @@ const P8PAppMessage = ({ variant, title, titleText, cancelBtn, onCancel, cancelB
|
||||
{titlePart}
|
||||
<DialogContent>
|
||||
<DialogContentText id="message-dialog-description" style={style.bodyText}>
|
||||
{text}
|
||||
{!showFullErrorText ? text : fullErrorText}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
{actionsPart}
|
||||
@ -148,7 +176,10 @@ P8PAppMessage.propTypes = {
|
||||
onOk: PropTypes.func,
|
||||
okBtnCaption: PropTypes.string,
|
||||
open: PropTypes.bool,
|
||||
text: PropTypes.string
|
||||
text: PropTypes.string,
|
||||
fullErrorText: PropTypes.string,
|
||||
showErrMoreCaption: PropTypes.string,
|
||||
hideErrMoreCaption: PropTypes.string
|
||||
};
|
||||
|
||||
//Встроенное сообщение
|
||||
|
@ -10,6 +10,7 @@
|
||||
import React, { createContext, useContext, useCallback } from "react"; //ReactJS
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { MessagingСtx } from "./messaging"; //Контекст сообщений
|
||||
import { formatErrorMessage } from "../core/utils"; //Вспомогательные функции
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
@ -80,7 +81,12 @@ export const BackEndContext = ({ client, children }) => {
|
||||
if (fullResponse === true || isRespErr(result)) return result;
|
||||
else return result.XPAYLOAD;
|
||||
} catch (e) {
|
||||
if (showErrorMessage) showMsgErr(e.message);
|
||||
if (showErrorMessage) {
|
||||
//Разбираем текст ошибки
|
||||
let errMsg = formatErrorMessage(e.message);
|
||||
//Отображаем ошибку
|
||||
showMsgErr(errMsg.text, null, errMsg.fullErrorText);
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
if (loader !== false) hideLoader();
|
||||
|
@ -33,7 +33,9 @@ const MESSAGING_CONTEXT_TEXTS_SHAPE = PropTypes.shape({
|
||||
const MESSAGING_CONTEXT_BUTTONS_SHAPE = PropTypes.shape({
|
||||
CLOSE: PropTypes.string.isRequired,
|
||||
OK: PropTypes.string.isRequired,
|
||||
CANCEL: PropTypes.string.isRequired
|
||||
CANCEL: PropTypes.string.isRequired,
|
||||
DETAIL: PropTypes.string.isRequired,
|
||||
HIDE: PropTypes.string.isRequired
|
||||
});
|
||||
|
||||
//----------------
|
||||
@ -56,12 +58,16 @@ export const MessagingContext = ({ titles, texts, buttons, children }) => {
|
||||
|
||||
//Отображение сообщения
|
||||
const showMsg = useCallback(
|
||||
(type, text, msgOnOk = null, msgOnCancel = null) => dispatch({ type: MSG_AT.SHOW_MSG, payload: { type, text, msgOnOk, msgOnCancel } }),
|
||||
(type, text, msgOnOk = null, msgOnCancel = null, fullErrorText = null) =>
|
||||
dispatch({ type: MSG_AT.SHOW_MSG, payload: { type, text, msgOnOk, msgOnCancel, fullErrorText } }),
|
||||
[]
|
||||
);
|
||||
|
||||
//Отображение сообщения - ошибка
|
||||
const showMsgErr = useCallback((text, msgOnOk = null) => showMsg(MSG_TYPE.ERR, text, msgOnOk), [showMsg]);
|
||||
const showMsgErr = useCallback(
|
||||
(text, msgOnOk = null, fullErrorText = null) => showMsg(MSG_TYPE.ERR, text, msgOnOk, null, fullErrorText),
|
||||
[showMsg]
|
||||
);
|
||||
|
||||
//Отображение сообщения - информация
|
||||
const showMsgInfo = useCallback((text, msgOnOk = null) => showMsg(MSG_TYPE.INFO, text, msgOnOk), [showMsg]);
|
||||
@ -126,6 +132,7 @@ export const MessagingContext = ({ titles, texts, buttons, children }) => {
|
||||
open={true}
|
||||
variant={state.msgType}
|
||||
text={state.msgText}
|
||||
fullErrorText={state.msgFullErrorText}
|
||||
title
|
||||
titleText={state.msgType == MSG_TYPE.ERR ? titles.ERR : state.msgType == MSG_TYPE.WARN ? titles.WARN : titles.INFO}
|
||||
okBtn={true}
|
||||
@ -134,6 +141,8 @@ export const MessagingContext = ({ titles, texts, buttons, children }) => {
|
||||
cancelBtn={state.msgType == MSG_TYPE.WARN}
|
||||
onCancel={handleMessageCancelClick}
|
||||
cancelBtnCaption={buttons.CANCEL}
|
||||
showErrMoreCaption={buttons.DETAIL}
|
||||
hideErrMoreCaption={buttons.HIDE}
|
||||
/>
|
||||
) : null}
|
||||
{children}
|
||||
|
@ -35,6 +35,7 @@ const INITIAL_STATE = {
|
||||
msg: false,
|
||||
msgType: MSG_TYPE.ERR,
|
||||
msgText: null,
|
||||
msgFullErrorText: null,
|
||||
msgOnOk: null,
|
||||
msgOnCancel: null
|
||||
};
|
||||
@ -59,6 +60,7 @@ const handlers = {
|
||||
msg: true,
|
||||
msgType: payload.type || MSG_TYPE.APP_ERR,
|
||||
msgText: payload.text,
|
||||
msgFullErrorText: payload.fullErrorText,
|
||||
msgOnOk: payload.msgOnOk,
|
||||
msgOnCancel: payload.msgOnCancel
|
||||
}),
|
||||
|
@ -158,6 +158,34 @@ const formatDateJSONDateOnly = value => (value ? dayjs(value).format("YYYY-MM-DD
|
||||
//Форматирование числа в "Денежном" формате РФ
|
||||
const formatNumberRFCurrency = value => (hasValue(value) ? new Intl.NumberFormat("ru-RU", { minimumFractionDigits: 2 }).format(value) : null);
|
||||
|
||||
//Форматирование текста ошибки
|
||||
const formatErrorMessage = errorMsg => {
|
||||
//Инициализируем текст заголовка ошибки
|
||||
let text = "";
|
||||
//Пробуем извлечь заголовок текста ошибки
|
||||
try {
|
||||
//Если это ошибка Oracle
|
||||
if (errorMsg.match(/^ORA-/)) {
|
||||
//Считываем первую строку с заголовочным текстом ошибки
|
||||
text = errorMsg.match(/^.*(?=(\nORA-))/)[0];
|
||||
//Убираем лишнюю информацию и пробелы
|
||||
text = text.replace(/ORA-\d*:/g, "").trim();
|
||||
}
|
||||
//Если это ошибка PG
|
||||
if (errorMsg.match(/^SQL Error/)) {
|
||||
//Считываем первую строку с заголовочным текстом ошибки
|
||||
text = errorMsg.match(/.*(?=(\n.*Where)|(.*Where))/)[0];
|
||||
//Убираем лишнюю информацию и пробелы
|
||||
text = text.replace(/SQL Error \[\d*\]: ERROR:/g, "").trim();
|
||||
}
|
||||
} catch {
|
||||
//Если произошла ошибка - оставляем полный текст ошибки
|
||||
text = errorMsg;
|
||||
}
|
||||
//Возвращаем результат
|
||||
return { text: text || errorMsg, fullErrorText: text ? errorMsg : null };
|
||||
};
|
||||
|
||||
//Формирование уникального идентификатора
|
||||
const genGUID = () =>
|
||||
"10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
|
||||
@ -178,5 +206,6 @@ export {
|
||||
formatDateTimeRF,
|
||||
formatDateJSONDateOnly,
|
||||
formatNumberRFCurrency,
|
||||
formatErrorMessage,
|
||||
genGUID
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user