diff --git a/lib/static/components/details.jsx b/lib/static/components/details.jsx
index 86e3a121b..c055e9775 100644
--- a/lib/static/components/details.jsx
+++ b/lib/static/components/details.jsx
@@ -3,7 +3,8 @@
import React, {useContext, useLayoutEffect, useState} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import {isEmpty, isFunction} from 'lodash';
+import stringify from 'json-stringify-safe';
+import {isEmpty, isFunction, isPlainObject} from 'lodash';
import {Disclosure} from '@gravity-ui/uikit';
import {MeasurementContext} from './measurement-context';
@@ -28,8 +29,10 @@ export default function Details(props) {
return null;
}
- const children = props.asHtml ? null : getContent();
- const extraProps = props.asHtml ? {dangerouslySetInnerHTML: {__html: getContent()}} : {};
+ const content = getContent();
+ const isObjectContent = isPlainObject(content) && !React.isValidElement(content);
+ const children = props.asHtml ? null : isObjectContent ? stringify(content) : content;
+ const extraProps = props.asHtml ? {dangerouslySetInnerHTML: {__html: content}} : {};
return
{children}
diff --git a/lib/static/new-ui/components/ErrorInfo/index.tsx b/lib/static/new-ui/components/ErrorInfo/index.tsx
index 8e8cc972a..589ba991b 100644
--- a/lib/static/new-ui/components/ErrorInfo/index.tsx
+++ b/lib/static/new-ui/components/ErrorInfo/index.tsx
@@ -4,9 +4,10 @@ import escapeHtml from 'escape-html';
import React, {ReactNode} from 'react';
import styles from './index.module.css';
+import stringify from 'json-stringify-safe';
interface ErrorInfoProps {
- name: string;
+ name: unknown;
stack?: string;
className?: string;
style?: React.CSSProperties;
@@ -17,5 +18,15 @@ export function ErrorInfo(props: ErrorInfoProps): ReactNode {
reset: ['eee', '00000000']
});
- return
;
+ let errorName = props.name;
+
+ if (typeof errorName !== 'string') {
+ try {
+ errorName = stringify(errorName);
+ } catch {
+ errorName = String(errorName);
+ }
+ }
+
+ return
;
}
diff --git a/test/unit/lib/static/components/details.jsx b/test/unit/lib/static/components/details.jsx
index eae489a2a..4efdc18e1 100644
--- a/test/unit/lib/static/components/details.jsx
+++ b/test/unit/lib/static/components/details.jsx
@@ -78,4 +78,32 @@ describe('
', () => {
const expectedHtml = '
' + props.content + '
';
assert.equal(component.container.querySelector('.details__content').parentNode.innerHTML, expectedHtml);
});
+
+ it('should stringify plain object content', async () => {
+ const user = userEvent.setup();
+ const content = {foo: 'bar'};
+ content.self = content;
+ const props = {
+ title: 'some-title',
+ content: () => content
+ };
+
+ const component = render(
);
+ await user.click(component.container.querySelector('.details__summary'));
+
+ assert.equal(component.container.querySelector('.details__content').textContent, '{"foo":"bar","self":"[Circular ~]"}');
+ });
+
+ it('should render react node content as is', async () => {
+ const user = userEvent.setup();
+ const props = {
+ title: 'some-title',
+ content: () =>
some content
+ };
+
+ const component = render(
);
+ await user.click(component.container.querySelector('.details__summary'));
+
+ assert.equal(component.container.querySelector('.some-content').textContent, 'some content');
+ });
});