Skip to content

Commit f710f44

Browse files
authored
fix(issues): Handle breadcrumb item as array (#93784)
1 parent 8b285b7 commit f710f44

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

static/app/components/events/breadcrumbs/breadcrumbItemContent.spec.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ describe('BreadcrumbItemContent', function () {
123123
itemWithoutValue.unmount();
124124
});
125125

126+
it('renders exception crumbs with array of objects', function () {
127+
const breadcrumb: BreadcrumbTypeDefault = {
128+
type: BreadcrumbType.ERROR,
129+
level: BreadcrumbLevelType.ERROR,
130+
data: {
131+
type: 'ValidationError',
132+
value: [
133+
{field: 'email', error: 'invalid'},
134+
{field: 'password', error: 'too short'},
135+
],
136+
},
137+
};
138+
render(<BreadcrumbItemContent breadcrumb={breadcrumb} />);
139+
expect(
140+
screen.getByText(
141+
'ValidationError: {"field":"email","error":"invalid"}, {"field":"password","error":"too short"}'
142+
)
143+
).toBeInTheDocument();
144+
});
145+
126146
it('applies item limits with fullyExpanded', function () {
127147
const longMessage = 'longMessage'.repeat(100);
128148
const breadcrumb: BreadcrumbTypeDefault = {

static/app/components/events/breadcrumbs/breadcrumbItemContent.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,20 @@ function SQLCrumbContent({
192192
);
193193
}
194194

195+
const formatValue = (val: unknown): string => {
196+
if (val === null || val === undefined) {
197+
return '';
198+
}
199+
if (Array.isArray(val)) {
200+
// Array might contain objects
201+
return val.map(item => formatValue(item)).join(', ');
202+
}
203+
if (typeof val === 'object') {
204+
return JSON.stringify(val);
205+
}
206+
return `${val as string | number}`;
207+
};
208+
195209
function ExceptionCrumbContent({
196210
breadcrumb,
197211
meta,
@@ -204,11 +218,15 @@ function ExceptionCrumbContent({
204218
meta?: Record<string, any>;
205219
}) {
206220
const {type, value, ...otherData} = breadcrumb?.data ?? {};
221+
222+
const hasValue = value !== null && value !== undefined && value !== '';
223+
const formattedValue = hasValue ? formatValue(value) : '';
224+
207225
return (
208226
<Fragment>
209227
<BreadcrumbText>
210-
{type && type}
211-
{type ? value && `: ${value}` : value && value}
228+
{type ? type : null}
229+
{type && hasValue ? `: ${formattedValue}` : hasValue ? formattedValue : null}
212230
</BreadcrumbText>
213231
{children}
214232
{Object.keys(otherData).length > 0 ? (

static/app/components/events/breadcrumbs/breadcrumbsTimeline.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import moment from 'moment-timezone';
55
import {Tooltip} from 'sentry/components/core/tooltip';
66
import {DateTime} from 'sentry/components/dateTime';
77
import Duration from 'sentry/components/duration';
8+
import ErrorBoundary from 'sentry/components/errorBoundary';
89
import BreadcrumbItemContent from 'sentry/components/events/breadcrumbs/breadcrumbItemContent';
910
import type {EnhancedCrumb} from 'sentry/components/events/breadcrumbs/utils';
1011
import {Timeline} from 'sentry/components/timeline';
@@ -60,7 +61,7 @@ export default function BreadcrumbsTimeline({
6061
estimateSize: () => 35,
6162
// Must match rendered item margins.
6263
gap: 8,
63-
overscan: 10,
64+
overscan: 25,
6465
});
6566

6667
if (!breadcrumbs.length) {
@@ -118,11 +119,13 @@ export default function BreadcrumbsTimeline({
118119
showLastLine={showLastLine}
119120
>
120121
<ContentWrapper>
121-
<BreadcrumbItemContent
122-
breadcrumb={breadcrumb}
123-
meta={meta}
124-
fullyExpanded={fullyExpanded}
125-
/>
122+
<ErrorBoundary mini>
123+
<BreadcrumbItemContent
124+
breadcrumb={breadcrumb}
125+
meta={meta}
126+
fullyExpanded={fullyExpanded}
127+
/>
128+
</ErrorBoundary>
126129
</ContentWrapper>
127130
</BreadcrumbItem>
128131
);

0 commit comments

Comments
 (0)